This document aims at exploring the dataset of 4 individuals in 2018. For that purpose, we need first to load the weanlingNES package to load data.
For convenience, we aggregate all 4 individuals into one dataset.
Some explanatory plots
Missing values
# build dataset to check for missing values
dataPlot <- melt(data_2018[, .(.id, is.na(.SD)), .SDcol = -c(
".id",
"divenumber",
"year",
"month",
"day",
"hour",
"min",
"sec",
"juldate",
"divetype",
"date",
"phase",
"lat",
"lon"
)])
# add the id of rows
dataPlot[, id_row := c(1:.N), by = c("variable", ".id")]
# plot
ggplot(dataPlot, aes(x = variable, y = id_row, fill = value)) +
geom_tile() +
labs(x = "Attributes", y = "Rows") +
scale_fill_manual(
values = c("white", "black"),
labels = c("Real", "Missing")
) +
facet_wrap(.id ~ ., scales = "free_y") +
theme_jjo() +
theme(
legend.position = "top",
axis.text.x = element_text(angle = 45, hjust = 1),
legend.key = element_rect(colour = "black")
)
So far so good, only few variables seems to have missing values:
# table with percent
table_inter <- data_2018[, lapply(.SD, function(x) {
round(length(x[is.na(x)]) * 100 / length(x), 1)
}), .SDcol = -c(
".id",
"divenumber",
"year",
"month",
"day",
"hour",
"min",
"sec",
"juldate",
"divetype",
"date",
"phase",
"lat",
"lon"
)]
# find which are different from 0
cond_inter <- sapply(table_inter, function(x) {
x == 0
})
# display the percentages that are over 0
table_inter[, which(cond_inter) := NULL] %>%
sable(caption = "Percentage of missing values per columns having missing values!") %>%
scroll_box(width = "100%")
Table 3: Percentage of missing values per columns having missing values!
|
lightatsurf
|
lattenuation
|
euphoticdepth
|
thermoclinedepth
|
driftrate
|
benthicdivevertrate
|
cornerindex
|
foragingindex
|
verticalspeed90perc
|
verticalspeed95perc
|
dist_dep
|
temp
|
ssh
|
psu
|
vel
|
bathy
|
|
26.3
|
89
|
62.6
|
1.3
|
0.5
|
22.7
|
75.8
|
0.5
|
0.1
|
0.1
|
35.1
|
35.1
|
35.1
|
35.1
|
35.1
|
35.1
|
Outliers
Ok, let’s have a look at all the data. But first, we have to remove outliers. Some of them are quiet easy to spot looking at the distribution of dive duration:
Before
ggplot(
data_2018[, .SD][, state := "Before"],
aes(x = dduration, fill = .id)
) +
geom_histogram(show.legend = FALSE) +
geom_vline(xintercept = 3000, linetype = "longdash") +
facet_grid(state ~ .id,
scales = "free"
) +
labs(y = "# of dives", x = "Dive duration (s)") +
theme_jjo()
After
ggplot(
data_2018[dduration < 3000, ][][, state := "After"],
aes(x = dduration, fill = .id)
) +
geom_histogram(show.legend = FALSE) +
geom_vline(xintercept = 3000, linetype = "longdash") +
facet_grid(state ~ .id,
scales = "free"
) +
labs(x = "# of dives", y = "Dive duration (s)") +
theme_jjo()
It seems much better, so let’s remove any rows with dduration > 3000 sec.
# filter data
data_2018_filter <- data_2018[dduration < 3000, ]
# nbrow removed
data_2018[dduration >= 3000, .(nb_row_removed = .N), by = .id] %>%
sable(caption = "# of rows removed by 2018-individuals")
Table 4: # of rows removed by 2018-individuals
|
.id
|
nb_row_removed
|
|
ind_2018070
|
3
|
|
ind_2018072
|
1
|
|
ind_2018074
|
33
|
Check day and night
Light levels
# let's first average `lightatsurf` by individuals, day since departure and hour
dataPlot <- data_2018[, .(lightatsurf = median(lightatsurf)),
by = .(.id, day_departure, date = as.Date(date), hour)
]
# display the result
ggplot(dataPlot, aes(x = day_departure, y = hour, fill = lightatsurf)) +
geom_tile() +
facet_grid(.id ~ .) +
theme_jjo() +
labs(x = "# of days since departure",
y = "Hour",
fill = "Light level at the surface")+
theme(legend.position = c("bottom"))
Day and night detection
# let's first average `lightatsurf` by individuals, day since departure and hour
dataPlot <- data_2018[, .(lightatsurf = median(lightatsurf)),
by = .(.id,
day_departure,
date = as.Date(date),
hour,
phase)
]
# display the result
ggplot(dataPlot, aes(x = day_departure, y = hour, fill = phase)) +
geom_tile() +
facet_grid(.id ~ .) +
theme_jjo() +
labs(x = "# of days since departure",
y = "Hour",
fill = "Day time and night time as detected by the `cal_phase_day` function") +
theme(legend.position = c("bottom"))
All Variables
names_display <- names(data_2018_filter[, -c(
".id",
"date",
"divenumber",
"year",
"month",
"day",
"hour",
"min",
"sec",
"juldate",
"divetype",
"euphoticdepth",
"thermoclinedepth",
"day_departure",
"phase",
"lat",
"lon",
"dist_dep",
"sp"
)])
# calulate the median of driftrate for each day
median_driftrate <- data_2018[divetype == "2: drift",
.(driftrate = quantile(driftrate, 0.5)),
by = .(date = as.Date(date), .id)
]
# let's identity when the smooth changes sign
changes_driftrate <- median_driftrate %>%
.[, .(
y_smooth = predict(loess(driftrate ~ as.numeric(date), span = 0.25)),
date
), by = .id] %>%
.[c(FALSE, diff(sign(y_smooth)) != 0), ]
for (i in names_display) {
cat("####", i, "{.unlisted .unnumbered} \n")
if (i == "maxdepth") {
print(
ggplot() +
geom_point(
data = data_2018_filter[, .(
.id,
date,
thermoclinedepth
)],
aes(
x = as.Date(date),
y = -thermoclinedepth,
colour = "Thermocline (m)"
),
alpha = .2,
size = .5
) +
geom_point(
data = data_2018_filter[, .(
.id,
date,
euphoticdepth
)],
aes(
x = as.Date(date),
y = -euphoticdepth,
colour = "Euphotic (m)"
),
alpha = .2,
size = .5
) +
scale_colour_manual(
values = c(
"Thermocline (m)" = "red",
"Euphotic (m)" = "black"
),
name = "Zone"
) +
new_scale_color() +
geom_point(
data = melt(data_2018_filter[, .(.id, date, get(i))],
id.vars = c(".id", "date")
),
aes(
x = as.Date(date),
y = -value,
col = .id
),
alpha = 1 / 10,
size = .5,
show.legend = FALSE
) +
geom_vline(
data = changes_driftrate,
aes(xintercept = date),
linetype = 2
) +
facet_wrap(. ~ .id, scales = "free") +
scale_x_date(date_labels = "%m/%Y") +
labs(x = "Date", y = "Maximum Depth (m)") +
theme_jjo() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "bottom"
))
cat("<blockquote> Considering `ind_2018074` has slightly different values than other individuals for the thermocline depth, it would be interesting to see where the animal went. </blockquote>")
} else if (i == "driftrate") {
print(
ggplot(
data = melt(data_2018_filter[, .(.id, date, get(i), divetype)],
id.vars = c(".id", "date", "divetype")),
aes(
x = as.Date(date),
y = value,
col = divetype
)
) +
geom_point(
alpha = 1 / 10,
size = .5
) +
geom_vline(
data = changes_driftrate,
aes(xintercept = date),
linetype = 2
) +
facet_wrap(. ~ .id, scales = "free") +
scale_x_date(date_labels = "%m/%Y") +
labs(x = "Date", y = "Drift Rate 'm/s", col = "Dive Type") +
theme_jjo() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "bottom"
) +
guides(colour = guide_legend(override.aes = list(
size = 7,
alpha = 1
)))
)
} else {
print(
ggplot(
data = melt(data_2018_filter[, .(.id, date, get(i))],
id.vars = c(".id", "date")),
aes(
x = as.Date(date),
y = value,
col = .id
)
) +
geom_point(
show.legend = FALSE,
alpha = 1 / 10,
size = .5
) +
geom_vline(
data = changes_driftrate,
aes(xintercept = date),
linetype = 2
) +
geom_vline(data = dataVline, aes(xintercept = as.Date(date)), colour = "black", linetype=2) +
facet_wrap(. ~ .id, scales = "free") +
scale_x_date(date_labels = "%m/%Y") +
labs(x = "Date", y = i) +
theme_jjo() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
)
}
cat("\n \n")
}
The vertical dashed lines represent changes in buoyancy (see vignette("buoyancy_detect") for more information)
maxdepth
Considering ind_2018074 has slightly different values than other individuals for the thermocline depth, it would be interesting to see where the animal went.
dduration

botttime

desctime

descrate

asctime

ascrate

pdi

dwigglesdesc

dwigglesbott

dwigglesasc

totvertdistbot

bottrange

efficiency

idz

lightatbott

lwiggles

lightatsurf

lattenuation

tempatsurf

tempatbott

driftdiveindex

driftrate

benthicdiveindex

benthicdivevertrate

cornerindex

foragingindex

verticalspeed90perc

verticalspeed95perc

sp

temp

ssh

psu

vel

bathy

Few questions, that I should look into it:
- is the bimodal distribution of
dduration, desctime due to nycthemeral migration?
- is the bimodal distribution of
descrate (especially for ind2018070 and ind_2018072) due to drift dive?
- is
lightatbott could be used to identify bioluminescence, cause it seems there is a lot going on at the bottom?
- are the variations observed for
lightatsurf is due to moon cycle?
- not sure why is there a bimodal distribution of
tempatbott!
drifrate that one is awesome! Thanks to divetype we can clearly see a pattern of how driftrate (and so buoyancy) change according time.
- the bimodal distribution of
verticalspeed90 and verticalspeed95 should be due to drift dive.
# same plot with a colored for the phase of the day
for (i in names_display) {
cat("####", i, "{-} \n")
print(
ggplot(
data = melt(data_2018_filter[, .(.id, date, get(i), phase)],
id.vars = c(
".id",
"date",
"phase"
)
),
aes(
x = as.Date(date),
y = value,
col = phase
)
) +
geom_point(
alpha = 1 / 10,
size = .5
) +
geom_vline(
data = changes_driftrate,
aes(xintercept = date),
linetype = 2
) +
facet_wrap(. ~ .id, scales = "free") +
scale_x_date(date_labels = "%m/%Y") +
labs(x = "Date", y = i) +
theme_jjo() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
legend.position = "bottom"
) +
guides(colour = guide_legend(override.aes = list(
size = 7,
alpha = 1
)))
)
cat("\n \n")
}
The vertical dashed lines represent changes in buoyancy (see vignette("buoyancy_detect") for more information)
maxdepth

dduration

botttime

desctime

descrate

asctime

ascrate

pdi

dwigglesdesc

dwigglesbott

dwigglesasc

totvertdistbot

bottrange

efficiency

idz

lightatbott

lwiggles

lightatsurf

lattenuation

tempatsurf

tempatbott

driftdiveindex

driftrate

benthicdiveindex

benthicdivevertrate

cornerindex

foragingindex

verticalspeed90perc

verticalspeed95perc

sp

temp

ssh

psu

vel

bathy

All Variables during the first month
for (i in names_display) {
cat("####", i, "{.unlisted .unnumbered} \n")
if (i == "maxdepth") {
print(
ggplot() +
geom_point(
data = data_2018_filter[day_departure < 32, .(
.id,
day_departure,
thermoclinedepth
)],
aes(
x = day_departure,
y = -thermoclinedepth,
colour = "Thermocline (m)",
group = day_departure
),
alpha = .2,
size = .5
) +
geom_point(
data = data_2018_filter[day_departure < 32, .(
.id,
day_departure,
euphoticdepth
)],
aes(
x = day_departure,
y = -euphoticdepth,
colour = "Euphotic (m)",
group = day_departure
),
alpha = .2,
size = .5
) +
scale_colour_manual(
values = c(
"Thermocline (m)" = "red",
"Euphotic (m)" = "black"
),
name = "Zone"
) +
new_scale_color() +
geom_boxplot(
data = melt(data_2018_filter[day_departure < 32,
.(.id, day_departure, get(i))],
id.vars = c(".id", "day_departure")),
aes(
x = day_departure,
y = -value,
col = .id,
group = day_departure
),
alpha = 1 / 10,
size = .5,
show.legend = FALSE
) +
facet_wrap(. ~ .id, scales = "free") +
labs(x = "# days since departure", y = "Maximum Depth (m)") +
theme_jjo() +
theme(legend.position = "bottom")
)
} else {
print(
ggplot(
data = melt(data_2018_filter[day_departure < 32,
.(.id, day_departure, get(i))],
id.vars = c(".id", "day_departure")),
aes(
x = day_departure,
y = value,
color = .id,
group = day_departure
)
) +
geom_boxplot(
show.legend = FALSE,
alpha = 1 / 10,
size = .5
) +
facet_wrap(. ~ .id, scales = "free") +
labs(x = "# days since departure", y = i) +
theme_jjo()
)
}
cat("\n \n")
}
maxdepth

dduration

botttime

desctime

descrate

asctime

ascrate

pdi

dwigglesdesc

dwigglesbott

dwigglesasc

totvertdistbot

bottrange

efficiency

idz

lightatbott

lwiggles

lightatsurf

lattenuation

tempatsurf

tempatbott

driftdiveindex

driftrate

benthicdiveindex

benthicdivevertrate

cornerindex

foragingindex

verticalspeed90perc

verticalspeed95perc

sp

temp

ssh

psu

vel

bathy

for (i in names_display) {
cat("####", i, "{.unlisted .unnumbered} \n")
print(
ggplot(
data = melt(data_2018_filter[
day_departure < 32,
.(.id, day_departure, get(i), phase)
],
id.vars = c(".id", "day_departure", "phase")
),
aes(
x = day_departure,
y = value,
color = phase,
group = interaction(day_departure, phase),
)
) +
geom_boxplot(
alpha = 1 / 10,
size = .5
) +
facet_wrap(. ~ .id, scales = "free") +
labs(x = "# days since departure", y = i) +
theme_jjo() +
theme(legend.position = "bottom")
)
cat("\n \n")
}
maxdepth

dduration

botttime

desctime

descrate

asctime

ascrate

pdi

dwigglesdesc

dwigglesbott

dwigglesasc

totvertdistbot

bottrange

efficiency

idz

lightatbott

lwiggles

lightatsurf

lattenuation

tempatsurf

tempatbott

driftdiveindex

driftrate

benthicdiveindex

benthicdivevertrate

cornerindex

foragingindex

verticalspeed90perc

verticalspeed95perc

sp

temp

ssh

psu

vel

bathy

Correlation
Can we find nice correlation?
# compute correlation
corr_2018 <- round(cor(data_2018_filter[, names_display, with = F],
use = "pairwise.complete.obs"
), 1)
# replace NA value by 0
corr_2018[is.na(corr_2018)] <- 0
# compute p_values
corr_p_2018 <- cor_pmat(data_2018_filter[, names_display, with = F])
# replace NA value by 0
corr_p_2018[is.na(corr_p_2018)] <- 1
# display
ggcorrplot(
corr_2018,
p.mat = corr_p_2018,
hc.order = TRUE,
method = "circle",
type = "lower",
ggtheme = theme_jjo(),
sig.level = 0.05,
colors = c("#00AFBB", "#E7B800", "#FC4E07")
)
Another way to see it:
# flatten correlation matrix
cor_result_2018 <- flat_cor_mat(corr_2018, corr_p_2018)
# keep only the one above .7
cor_result_2018[cor >= .7, ][order(-abs(cor))] %>%
sable(caption = "Pairwise correlation above 0.75 and associated p-values")
Table 5: Pairwise correlation above 0.75 and associated p-values
|
row
|
column
|
cor
|
p
|
|
verticalspeed90perc
|
verticalspeed95perc
|
1.0
|
0
|
|
tempatsurf
|
temp
|
0.9
|
0
|
|
maxdepth
|
asctime
|
0.8
|
0
|
|
botttime
|
efficiency
|
0.8
|
0
|
|
dwigglesbott
|
foragingindex
|
0.8
|
0
|
|
maxdepth
|
dduration
|
0.7
|
0
|
|
maxdepth
|
desctime
|
0.7
|
0
|
|
dduration
|
desctime
|
0.7
|
0
|
|
dduration
|
asctime
|
0.7
|
0
|
|
totvertdistbot
|
bottrange
|
0.7
|
0
|
|
totvertdistbot
|
verticalspeed90perc
|
0.7
|
0
|
|
totvertdistbot
|
verticalspeed95perc
|
0.7
|
0
|
I guess nothing unexpected here, I’ll have to check with Patrick about the efficiency ;)
Drift Rate
In the following graphs:
driftrate is calculated using only divetype == "2: drift"
- whereas all the others variables are calculated all dives considered
# build dataset
dataPlot <- data_2018_filter[divetype == "2: drift",
# median drift rate for drift dive
.(driftrate = median(driftrate, na.rm = T)),
by = .(.id, day_departure)
][data_2018_filter[,
.(
# median dive duration all dives considered
dduration = median(dduration, na.rm = T),
# median max depth all dives considered
maxdepth = median(maxdepth, na.rm = T),
# median bottom dives all dives considered
botttime = median(botttime, na.rm = T)
),
by = .(.id, day_departure)
],
on = c(".id", "day_departure")
]
# plot
ggplot(dataPlot, aes(x = botttime, y = driftrate, col = .id)) +
geom_point(size = .5, alpha = .5) +
geom_smooth(method = "lm") +
guides(color = "none") +
facet_wrap(.id ~ .) +
scale_x_continuous(limits = c(0, 700)) +
labs(x = "Daily median Bottom time (s)",
y = "Daily median drift rate (m.s-1)") +
theme_jjo()
# plot
ggplot(dataPlot, aes(x = maxdepth, y = driftrate, col = .id)) +
geom_point(size = .5, alpha = .5) +
geom_smooth(method = "lm") +
guides(color = "none") +
facet_wrap(.id ~ .) +
labs(x = "Daily median Maximum depth (m)",
y = "Daily median drift rate (m.s-1)") +
theme_jjo()
# plot
ggplot(dataPlot, aes(x = dduration, y = driftrate, col = .id)) +
geom_point(size = .5, alpha = .5) +
geom_smooth(method = "lm") +
guides(color = "none") +
facet_wrap(.id ~ .) +
labs(x = "Daily median Dive duration (s)",
y = "Daily median drift rate (m.s-1)") +
theme_jjo()
Behavioral Aerobic Dive Limit (bADL)
# dive duration vs pdi by days
ggplot(data = data_2018_filter[pdi < 300, ], aes(
x = dduration,
y = pdi,
color = .id,
group = dduration,
fill = "none"
)) +
geom_boxplot(show.legend = FALSE, outlier.alpha = 0.05, alpha = 0) +
labs(x = "Dive duration (s)", y = "Post-dive duration (s)") +
facet_wrap(. ~ .id, scales = "free_x") +
theme_jjo()
# dive duration vs pdi by days
ggplot(data = data_2018_filter[pdi < 300,], aes(x = dduration,
y = pdi,
color = .id)) +
geom_point(show.legend = FALSE, alpha = 0.05) +
geom_smooth(
method = "gam",
show.legend = FALSE,
col = "black",
linetype = "dashed"
) +
labs(x = "Dive duration (s)", y = "Post-dive duration (s)") +
facet_wrap(. ~ .id, scales = "free_x") +
theme_jjo()
# dive duration vs pdi by days
ggplot(
data = data_2018_filter[pdi < 300, .(.id, pdi_ratio = pdi / dduration, day_departure)],
aes(
x = day_departure,
y = pdi_ratio,
color = .id,
group = day_departure,
fill = "none"
)
) +
geom_boxplot(show.legend = FALSE,
outlier.alpha = 0.05,
alpha = 0) +
labs(x = "# days since departure", y = "Post-dive / Dive duration ratio") +
facet_wrap(. ~ .id, scales = "free_x") +
# zoom
coord_cartesian(ylim = c(0, 0.4)) +
theme_jjo()
Based on Shero et al. (2018), we decided to look at the bADL as the 95th percentile of dive duration each day, for those with \(n \geq 50\). This threshold was chosen following this figure:
ggplot(data_2018_filter[,.(nb_dives = .N),
by = .(.id, day_departure)],
aes(x=nb_dives, fill=.id)) +
geom_histogram(show.legend = FALSE) +
facet_grid(.~.id) +
labs(y="# of days", x = "# of dives per day") +
theme_jjo()
# select day that have at least 50 dives
days_to_keep = data_2018_filter[,
.(nb_dives = .N),
by = .(.id, day_departure)] %>%
.[nb_dives >= 50,]
# keep only those days
data_2018_filter_complete_day = merge(data_2018_filter,
days_to_keep,
by = c(".id", "day_departure"))
# data plot
dataPlot = data_2018_filter_complete_day[divetype=="1: foraging",
.(badl = quantile(dduration, 0.95)),
by = .(.id, day_departure)]
# combine two datasets to be able to use a second axis
# https://stackoverflow.com/questions/49185583/two-y-axes-with-different-scales-for-two-datasets-in-ggplot2
dataMegaPlot = rbind(data_2018_filter_complete_day[divetype == "2: drift"] %>%
.[, .(w = .id,
y = driftrate,
x = day_departure,
z = "second_plot")],
dataPlot[, .(
w = .id,
# tricky one
y = (badl / 1000) - 1,
x = day_departure,
z = "first_plot"
)])
# plot
ggplot() +
geom_point(
data = dataMegaPlot[z == "second_plot", ],
aes(x = x, y = y),
alpha = 1 / 10,
size = 0.5,
color = "grey40",
show.legend = FALSE
) +
geom_path(data = dataMegaPlot[z == "first_plot", ],
aes(x = x, y = y, color = w),
show.legend = FALSE) +
scale_y_continuous(
# Features of the first axis
name = "Drift rate (m/s)",
# Add a second axis and specify its features
sec.axis = sec_axis( ~ (. * 1000) + 1000,
name = "Behavioral Aerobic Dive Limit (s)")
) +
labs(x = "# days since departure") +
facet_wrap(w ~ .) +
theme_jjo()
Looking at this graph, I want to believe that there is some kind of relationship between the bADL as defined by Shero et al. (2018) and the drift rate (and so buyoancy).
# get badl
dataplot_1 = data_2018_filter_complete_day[,
.(badl = quantile(dduration, 0.95)),
by = .(.id, day_departure)]
# get driftrate
dataplot_2 = data_2018_filter_complete_day[divetype == "2: drift",
.(driftrate = median(driftrate)),
by = .(.id, day_departure)]
# merge
dataPlot = merge(dataplot_1,
dataplot_2,
by = c(".id", "day_departure"),
all = TRUE)
# plot
ggplot(data = dataPlot, aes(x = badl, y = driftrate, col = .id)) +
geom_point(show.legend = FALSE) +
facet_wrap(.id~., scales = "free") +
theme_jjo()

ind_2018070
# ind_2018070
plot_ly(
x = dataPlot[.id == "ind_2018070", badl],
y = dataPlot[.id == "ind_2018070", day_departure],
z = dataPlot[.id == "ind_2018070", driftrate],
type = "scatter3d",
mode = "markers",
marker = list(size = 2),
color = dataPlot[.id == "ind_2018070", day_departure]
) %>%
layout(scene = list(xaxis = list(title = 'Behavioral ADL'),
yaxis = list(title = '# days since departure'),
zaxis = list(title = 'Drift rate (m/s)')))
ind_2018072
# ind_2018072
plot_ly(
x = dataPlot[.id == "ind_2018072", badl],
y = dataPlot[.id == "ind_2018072", day_departure],
z = dataPlot[.id == "ind_2018072", driftrate],
type = "scatter3d",
mode = "markers",
marker = list(size = 2),
color = dataPlot[.id == "ind_2018072", day_departure]
) %>%
layout(scene = list(xaxis = list(title = 'Behavioral ADL'),
yaxis = list(title = '# days since departure'),
zaxis = list(title = 'Drift rate (m/s)')))
ind_2018074
# ind_2018074
plot_ly(
x = dataPlot[.id == "ind_2018074", badl],
y = dataPlot[.id == "ind_2018074", day_departure],
z = dataPlot[.id == "ind_2018074", driftrate],
type = "scatter3d",
mode = "markers",
marker = list(size = 2),
color = dataPlot[.id == "ind_2018074", day_departure]
) %>%
layout(scene = list(xaxis = list(title = 'Behavioral ADL'),
yaxis = list(title = '# days since departure'),
zaxis = list(title = 'Drift rate (m/s)')))
ind_2018072
# ind_2018080
plot_ly(
x = dataPlot[.id == "ind_2018080", badl],
y = dataPlot[.id == "ind_2018080", day_departure],
z = dataPlot[.id == "ind_2018080", driftrate],
type = "scatter3d",
mode = "markers",
marker = list(size = 2),
color = dataPlot[.id == "ind_2018080", day_departure]
) %>%
layout(scene = list(xaxis = list(title = 'Behavioral ADL'),
yaxis = list(title = '# days since departure'),
zaxis = list(title = 'Drift rate (m/s)')))
LS0tCnRpdGxlOiAiRGF0YSBFeHBsb3JhdGlvbiAtIDIwMTgiCmF1dGhvcjogIkpvZmZyZXkgSk9VTUFBIgpkYXRlOiAiYHIgaW52aXNpYmxlKFN5cy5zZXRsb2NhbGUobG9jYWxlID0gJ0MnKSk7IGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQgPSAnJUIgJWQsICVZJylgIgpvdXRwdXQ6CiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgY3NzOiBjb3Ntb19jdXN0b20uY3NzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBkZl9wcmludDogZGVmYXVsdAogICAgZmlnX2NhcHRpb246IHllcwogICAgY29kZV9kb3dubG9hZDogeWVzCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHllcwogICAgICBzbW9vdGhfc2Nyb2xsOiBubwpsaW5rLWNpdGF0aW9uczogeWVzCnBrZ2Rvd246CiAgYXNfaXM6IGZhbHNlCnZpZ25ldHRlOiA+CiAgJVxWaWduZXR0ZUluZGV4RW50cnl7RGF0YSBFeHBsb3JhdGlvbiAtIDIwMTh9CiAgJVxWaWduZXR0ZUVuZ2luZXtrbml0cjo6cm1hcmtkb3dufQogICVcVmlnbmV0dGVFbmNvZGluZ3tVVEYtOH0KLS0tCiAgCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQojIGNvbW1hbmQgdG8gYnVpbGQgcGFja2FnZSB3aXRob3V0IGdldHRpbmcgdmlnbmV0dGUgZXJyb3IKIyBodHRwczovL2dpdGh1Yi5jb20vcnN0dWRpby9yZW52L2lzc3Vlcy84MzMKIyBkZXZ0b29sczo6Y2hlY2soYnVpbGRfYXJncz1jKCItLW5vLWJ1aWxkLXZpZ25ldHRlcyIpKQoKIyByZWR1Y2UgcG5nIHNpemUKa25pdHI6OmtuaXRfaG9va3Mkc2V0KG9wdGlwbmcgPSBrbml0cjo6aG9va19vcHRpcG5nKQprbml0cjo6a25pdF9ob29rcyRzZXQocG5ncXVhbnQgPSBrbml0cjo6aG9va19wbmdxdWFudCkKCiMgZ2xvYmFsIG9wdGlvbiByZWxhdGl2ZSB0byBybWFya2Rvd24Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGNhY2hlID0gVFJVRSwKICBlY2hvID0gVFJVRSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBvdXQud2lkdGggPSAiMTAwJSIsCiAgbWVzc2FnZSA9IEZBTFNFLAogIHdhcm5pbmcgPSBGQUxTRSwKICAjIHRpZHkgPSBUUlVFLAogIGNhY2hlLmxhenkgPSBGQUxTRSwKICBvcHRpcG5nID0gIi1vNyAtcXVpZXQiLAogIHBuZ3F1YW50ID0gIi0tc3BlZWQ9MSIKKQoKIyBsaWJyYXJ5CmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkobGVhZmxldCkKbGlicmFyeShndHN1bW1hcnkpICMgaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2d0c3VtbWFyeS92aWduZXR0ZXMvdGJsX3N1bW1hcnkuaHRtbApsaWJyYXJ5KGNvcnJwbG90KQpsaWJyYXJ5KGdnY29ycnBsb3QpCmxpYnJhcnkoZ2duZXdzY2FsZSkKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeShEVCkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoZ2Vvc3BoZXJlKQpsaWJyYXJ5KHRpZHluYykKbGlicmFyeShnZ2FuaW1hdGUpCmxpYnJhcnkodHJhbnNmb3JtcikKbGlicmFyeShtYWdpY2spCmxpYnJhcnkoZ2lmc2tpKQoKIyByZW1vdmUgc29tZSB3YXJuaW5ncwpzdXBwcmVzc1dhcm5pbmdzKGxpYnJhcnkoZ2dwbG90MikpCgojIGRlZmluZSBteSBvd24gdGFibGUgZm9ybWF0OiBodHRwczovL2dpdGh1Yi5jb20vaGFvemh1MjMzL2thYmxlRXh0cmEvaXNzdWVzLzM3NApzYWJsZSA8LSBmdW5jdGlvbih4LCBlc2NhcGUgPSBULCAuLi4pIHsKICBrbml0cjo6a2FibGUoeCwgZXNjYXBlID0gZXNjYXBlLCAuLi4pICU+JQogICAga2FibGVfc3R5bGluZygKICAgICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgInJlc3BvbnNpdmUiKSwKICAgICAgZnVsbF93aWR0aCA9IEYKICAgICkKfQoKIyB0aGVtZSBnZ3Bsb3QKIyBiYXNlZDogaHR0cHM6Ly9iZW5qYW1pbmxvdWlzLXN0YXQuZnIvZW4vYmxvZy8yMDIwLTA1LTIxLWFzdHVjZXMtZ2dwbG90LXJtYXJrZG93bi8KdGhlbWVfampvIDwtIGZ1bmN0aW9uKGJhc2Vfc2l6ZSA9IDEyKSB7CiAgdGhlbWVfYncoYmFzZV9zaXplID0gYmFzZV9zaXplKSAlK3JlcGxhY2UlCiAgICB0aGVtZSgKICAgICAgIyB0aGUgd2hvbGUgZmlndXJlCiAgICAgICMgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDEpLCBmYWNlID0gImJvbGQiLCBtYXJnaW4gPSBtYXJnaW4oMCwwLDUsMCksIGhqdXN0ID0gMCksCiAgICAgICMgZmlndXJlIGFyZWEKICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLAogICAgICAjIGF4ZXMKICAgICAgIyBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSByZWwoMC44NSksIGZhY2UgPSAiYm9sZCIpLAogICAgICAjIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDAuNzApLCBmYWNlID0gImJvbGQiKSwKICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG9yID0gImJsYWNrIiwgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMiwgImxpbmVzIiksIHR5cGUgPSAiY2xvc2VkIikpLAogICAgICAjIGxlZ2VuZAogICAgICAjIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDAuODUpLCBmYWNlID0gImJvbGQiKSwKICAgICAgIyBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDAuNzApLCBmYWNlID0gImJvbGQiKSwKICAgICAgIyBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSksCiAgICAgICMgbGVnZW5kLmtleS5zaXplID0gdW5pdCgxLjUsICJsaW5lcyIpLAogICAgICAjIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSksCiAgICAgICMgTGVzIDxVKzAwRTk+dGlxdWV0dGVzIGRhbnMgbGUgY2FzIGQndW4gZmFjZXR0aW5nCiAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjODg4ODg4IiwgY29sb3IgPSAiIzg4ODg4OCIpLAogICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSByZWwoMC44NSksIGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gIndoaXRlIiwgbWFyZ2luID0gbWFyZ2luKDUsIDAsIDUsIDApKQogICAgKQp9CmBgYAoKVGhpcyBkb2N1bWVudCBhaW1zIGF0IGV4cGxvcmluZyB0aGUgZGF0YXNldCBvZiA0IGluZGl2aWR1YWxzIGluIDIwMTguIEZvciB0aGF0IHB1cnBvc2UsIHdlIG5lZWQgZmlyc3QgdG8gbG9hZCB0aGUgYHdlYW5saW5nTkVTYCBwYWNrYWdlIHRvIGxvYWQgZGF0YS4KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0xfQojIGxvYWQgbGlicmFyeQpsaWJyYXJ5KHdlYW5saW5nTkVTKQoKIyBsb2FkIGRhdGEKZGF0YSgiZGF0YV9uZXMiLCBwYWNrYWdlID0gIndlYW5saW5nTkVTIikKIyBsb2FkKCIuLi9kYXRhL2RhdGFfbmVzLnJkYSIpCmBgYAoKTGV04oCZcyBoYXZlIGEgbG9vayBhdCB3aGF04oCZcyBpbnNpZGUgYGRhdGFfbmVzJGRhdGFfMjAxOGA6CiAgCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0yfQojIGxpc3Qgc3RydWN0dXJlCnN0cihkYXRhX25lcyR5ZWFyXzIwMTgsIG1heC5sZXZlbCA9IDEsIGdpdmUuYXR0ciA9IEYsIG5vLmxpc3QgPSBUKQpgYGAKCj4gQSBsaXN0IG9mIGByIGxlbmd0aChkYXRhX25lcyR5ZWFyXzIwMTgpYCBgZGF0YS5mcmFtZXNgLCBvbmUgZm9yIGVhY2ggc2VhbAoKRm9yIGNvbnZlbmllbmNlLCB3ZSBhZ2dyZWdhdGUgYWxsIGByIGxlbmd0aChkYXRhX25lcyR5ZWFyXzIwMTgpYCBpbmRpdmlkdWFscyBpbnRvIG9uZSBkYXRhc2V0LgoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTMsIGV2YWw9RkFMU0V9CiMgY29tYmluZSBhbGwgaW5kaXZpZHVhbHMKZGF0YV8yMDE4IDwtIHJiaW5kbGlzdChkYXRhX25lcyR5ZWFyXzIwMTgpCgojIGRpc3BsYXkKRFQ6OmRhdGF0YWJsZShkYXRhXzIwMThbc2FtcGxlLmludCguTiwgMTApLCBdLCBvcHRpb25zID0gbGlzdChzY3JvbGxYID0gVCkpCmBgYApgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtNCwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9CiMgY29tYmluZSBhbGwgaW5kaXZpZHVhbHMKZGF0YV8yMDE4IDwtIHJiaW5kbGlzdChkYXRhX25lcyR5ZWFyXzIwMTgpCgojIHRpdGxlCmNhdCgiPHRhYmxlIHN0eWxlPSd3aWR0aDogNTAlJz4iLCAKICAgIHBhc3RlMCgKICAgICAgIjxjYXB0aW9uPiIsIAogICAgICAiKCN0YWI6bXlEVGh0bWx0b29scykiLCAKICAgICAgIlNhbXBsZSBvZiAxMCByYW5kb20gcm93cyBmcm9tIGBkYXRhXzIwMThgIiwgCiAgICAgICI8L2NhcHRpb24+IiksIAogICAgIjwvdGFibGU+IiwgCiAgICBzZXAgPSAiXG4iKQoKIyBkaXNwbGF5CkRUOjpkYXRhdGFibGUoZGF0YV8yMDE4W3NhbXBsZS5pbnQoLk4sIDEwKSwgXSwgb3B0aW9ucyA9IGxpc3Qoc2Nyb2xsWCA9IFQpKQpgYGAKCiMjIFN1bW1hcnkKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC01fQojIHJhd19kYXRhCmRhdGFfMjAxOFssIC4oCiAgbmJfZGF5c19yZWNvcmRlZCA9IHVuaXF1ZU4oYXMuRGF0ZShkYXRlKSksCiAgbmJfZGl2ZXMgPSAuTiwKICBtYXhkZXB0aF9tZWFuID0gbWVhbihtYXhkZXB0aCksCiAgZGR1cmF0aW9uX21lYW4gPSBtZWFuKGRkdXJhdGlvbiksCiAgYm90dHRpbWVfbWVhbiA9IG1lYW4oYm90dHRpbWUpLAogIHBkaV9tZWFuID0gbWVhbihwZGksIG5hLnJtID0gVCkKKSwgYnkgPSAuaWRdICU+JQogIHNhYmxlKAogICAgY2FwdGlvbiA9ICJTdW1tYXJ5IGRpdmluZyBpbmZvcm1hdGlvbiByZWxhdGl2ZSB0byBlYWNoIDIwMTggaW5kaXZpZHVhbCIsCiAgICBkaWdpdHMgPSAyCiAgKQpgYGAKPiBWZXJ5IG5pY2UgZGF0YXNldCA6KQoKIyMgU29tZSBleHBsYW5hdG9yeSBwbG90cwoKIyMjIE1pc3NpbmcgdmFsdWVzCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtNiwgZmlnLmNhcD0iQ2hlY2sgZm9yIG1pc3NpbmcgdmFsdWUgaW4gMjAxOC1pbmRpdmlkdWFscyIsIGZpZy53aWR0aD05fQojIGJ1aWxkIGRhdGFzZXQgdG8gY2hlY2sgZm9yIG1pc3NpbmcgdmFsdWVzCmRhdGFQbG90IDwtIG1lbHQoZGF0YV8yMDE4WywgLiguaWQsIGlzLm5hKC5TRCkpLCAuU0Rjb2wgPSAtYygKICAiLmlkIiwKICAiZGl2ZW51bWJlciIsCiAgInllYXIiLAogICJtb250aCIsCiAgImRheSIsCiAgImhvdXIiLAogICJtaW4iLAogICJzZWMiLAogICJqdWxkYXRlIiwKICAiZGl2ZXR5cGUiLAogICJkYXRlIiwKICAicGhhc2UiLAogICJsYXQiLAogICJsb24iCildKQojIGFkZCB0aGUgaWQgb2Ygcm93cwpkYXRhUGxvdFssIGlkX3JvdyA6PSBjKDE6Lk4pLCBieSA9IGMoInZhcmlhYmxlIiwgIi5pZCIpXQoKIyBwbG90CmdncGxvdChkYXRhUGxvdCwgYWVzKHggPSB2YXJpYWJsZSwgeSA9IGlkX3JvdywgZmlsbCA9IHZhbHVlKSkgKwogIGdlb21fdGlsZSgpICsKICBsYWJzKHggPSAiQXR0cmlidXRlcyIsIHkgPSAiUm93cyIpICsKICBzY2FsZV9maWxsX21hbnVhbCgKICAgIHZhbHVlcyA9IGMoIndoaXRlIiwgImJsYWNrIiksCiAgICBsYWJlbHMgPSBjKCJSZWFsIiwgIk1pc3NpbmciKQogICkgKwogIGZhY2V0X3dyYXAoLmlkIH4gLiwgc2NhbGVzID0gImZyZWVfeSIpICsKICB0aGVtZV9qam8oKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIpCiAgKQpgYGAKClNvIGZhciBzbyBnb29kLCBvbmx5IGZldyB2YXJpYWJsZXMgc2VlbXMgdG8gaGF2ZSBtaXNzaW5nIHZhbHVlczoKICAKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTd9CiMgdGFibGUgd2l0aCBwZXJjZW50CnRhYmxlX2ludGVyIDwtIGRhdGFfMjAxOFssIGxhcHBseSguU0QsIGZ1bmN0aW9uKHgpIHsKICByb3VuZChsZW5ndGgoeFtpcy5uYSh4KV0pICogMTAwIC8gbGVuZ3RoKHgpLCAxKQp9KSwgLlNEY29sID0gLWMoCiAgIi5pZCIsCiAgImRpdmVudW1iZXIiLAogICJ5ZWFyIiwKICAibW9udGgiLAogICJkYXkiLAogICJob3VyIiwKICAibWluIiwKICAic2VjIiwKICAianVsZGF0ZSIsCiAgImRpdmV0eXBlIiwKICAiZGF0ZSIsCiAgInBoYXNlIiwKICAibGF0IiwKICAibG9uIgopXQoKIyBmaW5kIHdoaWNoIGFyZSBkaWZmZXJlbnQgZnJvbSAwCmNvbmRfaW50ZXIgPC0gc2FwcGx5KHRhYmxlX2ludGVyLCBmdW5jdGlvbih4KSB7CiAgeCA9PSAwCn0pCgojIGRpc3BsYXkgdGhlIHBlcmNlbnRhZ2VzIHRoYXQgYXJlIG92ZXIgMAp0YWJsZV9pbnRlclssIHdoaWNoKGNvbmRfaW50ZXIpIDo9IE5VTExdICU+JQogIHNhYmxlKGNhcHRpb24gPSAiUGVyY2VudGFnZSBvZiBtaXNzaW5nIHZhbHVlcyBwZXIgY29sdW1ucyBoYXZpbmcgbWlzc2luZyB2YWx1ZXMhIikgJT4lCiAgc2Nyb2xsX2JveCh3aWR0aCA9ICIxMDAlIikKYGBgCgojIyMgT3V0bGllcnMgey50YWJzZXR9CgpPaywgbGV0J3MgaGF2ZSBhIGxvb2sgYXQgYWxsIHRoZSBkYXRhLiBCdXQgZmlyc3QsIHdlIGhhdmUgdG8gcmVtb3ZlIG91dGxpZXJzLiBTb21lIG9mIHRoZW0gYXJlIHF1aWV0IGVhc3kgdG8gc3BvdCBsb29raW5nIGF0IHRoZSBkaXN0cmlidXRpb24gb2YgZGl2ZSBkdXJhdGlvbjoKCiMjIyMgQmVmb3JlIHstfQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTgsIGZpZy5jYXA9J0Rpc3RyaWJ1dGlvbiBvZiBgZGR1cmF0aW9uYCBmb3IgZWFjaCBzZWFsLiBUaGUgZGFzaGVkIGxpbmUgaGlnaGxpZ2h0IHRoZSAic3ViamVjdGl2ZSIgdGhyZXNob2xkIHVzZWQgdG8gcmVtb3ZlIG91dGxpZXJzICgzMDAwIHNlYyknLCBmaWcuaGVpZ2h0PTN9CmdncGxvdCgKICBkYXRhXzIwMThbLCAuU0RdWywgc3RhdGUgOj0gIkJlZm9yZSJdLAogIGFlcyh4ID0gZGR1cmF0aW9uLCBmaWxsID0gLmlkKQopICsKICBnZW9tX2hpc3RvZ3JhbShzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMzAwMCwgbGluZXR5cGUgPSAibG9uZ2Rhc2giKSArCiAgZmFjZXRfZ3JpZChzdGF0ZSB+IC5pZCwKICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlIgogICkgKwogIGxhYnMoeSA9ICIjIG9mIGRpdmVzIiwgeCA9ICJEaXZlIGR1cmF0aW9uIChzKSIpICsKICB0aGVtZV9qam8oKQpgYGAKCiMjIyMgQWZ0ZXIgey19CgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtOSwgZmlnLmNhcD0nU2FtZSBkaXN0cmlidXRpb24gb2YgYGRkdXJhdGlvbmAgZm9yIGVhY2ggc2VhbCBidXQgYWZ0ZXIgcmVtb3ZpbmcgYW55IGBkZHVyYXRpb25gID4gMzAwMCBzZWMuIFRoZSBkYXNoZWQgbGluZSBoaWdobGlnaHQgdGhlICJzdWJqZWN0aXZlIiB0aHJlc2hvbGQgdXNlZCB0byByZW1vdmUgb3V0bGllcnMnLCBmaWcuaGVpZ2h0PTN9CmdncGxvdCgKICBkYXRhXzIwMThbZGR1cmF0aW9uIDwgMzAwMCwgXVtdWywgc3RhdGUgOj0gIkFmdGVyIl0sCiAgYWVzKHggPSBkZHVyYXRpb24sIGZpbGwgPSAuaWQpCikgKwogIGdlb21faGlzdG9ncmFtKHNob3cubGVnZW5kID0gRkFMU0UpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAzMDAwLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIpICsKICBmYWNldF9ncmlkKHN0YXRlIH4gLmlkLAogICAgICAgICAgICAgc2NhbGVzID0gImZyZWUiCiAgKSArCiAgbGFicyh4ID0gIiMgb2YgZGl2ZXMiLCB5ID0gIkRpdmUgZHVyYXRpb24gKHMpIikgKwogIHRoZW1lX2pqbygpCmBgYAoKSXQgc2VlbXMgbXVjaCBiZXR0ZXIsIHNvIGxldCdzIHJlbW92ZSBhbnkgcm93cyB3aXRoIGBkZHVyYXRpb25gID4gMzAwMCBzZWMuCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMTB9CiMgZmlsdGVyIGRhdGEKZGF0YV8yMDE4X2ZpbHRlciA8LSBkYXRhXzIwMThbZGR1cmF0aW9uIDwgMzAwMCwgXQoKIyBuYnJvdyByZW1vdmVkCmRhdGFfMjAxOFtkZHVyYXRpb24gPj0gMzAwMCwgLihuYl9yb3dfcmVtb3ZlZCA9IC5OKSwgYnkgPSAuaWRdICU+JQogIHNhYmxlKGNhcHRpb24gPSAiIyBvZiByb3dzIHJlbW92ZWQgYnkgMjAxOC1pbmRpdmlkdWFscyIpCmBgYAoKIyMjIENoZWNrIGRheSBhbmQgbmlnaHQgey50YWJzZXR9CgojIyMjIExpZ2h0IGxldmVscwoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTExLCBmaWcuY2FwPSJWaXN1YWxpemF0aW9uIG9mIGxpZ2h0IGxldmVsIGF0IHRoZSBzdXJmYWNlIGFsb25nIDIwMTgtaW5kaXZpZHVhbHMnIHRyaXAiLCBmaWcuaGVpZ2h0PTZ9CiMgbGV0J3MgZmlyc3QgYXZlcmFnZSBgbGlnaHRhdHN1cmZgIGJ5IGluZGl2aWR1YWxzLCBkYXkgc2luY2UgZGVwYXJ0dXJlIGFuZCBob3VyCmRhdGFQbG90IDwtIGRhdGFfMjAxOFssIC4obGlnaHRhdHN1cmYgPSBtZWRpYW4obGlnaHRhdHN1cmYpKSwKICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gLiguaWQsIGRheV9kZXBhcnR1cmUsIGRhdGUgPSBhcy5EYXRlKGRhdGUpLCBob3VyKQpdCgojIGRpc3BsYXkgdGhlIHJlc3VsdApnZ3Bsb3QoZGF0YVBsb3QsIGFlcyh4ID0gZGF5X2RlcGFydHVyZSwgeSA9IGhvdXIsIGZpbGwgPSBsaWdodGF0c3VyZikpICsKICBnZW9tX3RpbGUoKSArCiAgZmFjZXRfZ3JpZCguaWQgfiAuKSArCiAgdGhlbWVfampvKCkgKwogIGxhYnMoeCA9ICIjIG9mIGRheXMgc2luY2UgZGVwYXJ0dXJlIiwgCiAgICAgICB5ID0gIkhvdXIiLCAKICAgICAgIGZpbGwgPSAiTGlnaHQgbGV2ZWwgYXQgdGhlIHN1cmZhY2UiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKCJib3R0b20iKSkKYGBgCgojIyMjIERheSBhbmQgbmlnaHQgZGV0ZWN0aW9uCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMTIsIGZpZy5jYXA9IlZpc3VhbGl6YXRpb24gb2YgZGV0ZWN0ZWQgbmlnaHQgdGltZSBhbmQgZGF5IHRpbWUgYWxvbmcgMjAxOC1pbmRpdmlkdWFscycgdHJpcCIsIGZpZy5oZWlnaHQ9Nn0KIyBsZXQncyBmaXJzdCBhdmVyYWdlIGBsaWdodGF0c3VyZmAgYnkgaW5kaXZpZHVhbHMsIGRheSBzaW5jZSBkZXBhcnR1cmUgYW5kIGhvdXIKZGF0YVBsb3QgPC0gZGF0YV8yMDE4WywgLihsaWdodGF0c3VyZiA9IG1lZGlhbihsaWdodGF0c3VyZikpLAogICAgICAgICAgICAgICAgICAgICAgYnkgPSAuKC5pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF5X2RlcGFydHVyZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZSA9IGFzLkRhdGUoZGF0ZSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBoYXNlKQpdCgojIGRpc3BsYXkgdGhlIHJlc3VsdApnZ3Bsb3QoZGF0YVBsb3QsIGFlcyh4ID0gZGF5X2RlcGFydHVyZSwgeSA9IGhvdXIsIGZpbGwgPSBwaGFzZSkpICsKICBnZW9tX3RpbGUoKSArCiAgZmFjZXRfZ3JpZCguaWQgfiAuKSArCiAgdGhlbWVfampvKCkgKwogIGxhYnMoeCA9ICIjIG9mIGRheXMgc2luY2UgZGVwYXJ0dXJlIiwgCiAgICAgICB5ID0gIkhvdXIiLCAKICAgICAgIGZpbGwgPSAiRGF5IHRpbWUgYW5kIG5pZ2h0IHRpbWUgYXMgZGV0ZWN0ZWQgYnkgdGhlIGBjYWxfcGhhc2VfZGF5YCBmdW5jdGlvbiIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKCJib3R0b20iKSkKYGBgCgojIyMgQWxsIFZhcmlhYmxlcyAKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0xM30KbmFtZXNfZGlzcGxheSA8LSBuYW1lcyhkYXRhXzIwMThfZmlsdGVyWywgLWMoCiAgIi5pZCIsCiAgImRhdGUiLAogICJkaXZlbnVtYmVyIiwKICAieWVhciIsCiAgIm1vbnRoIiwKICAiZGF5IiwKICAiaG91ciIsCiAgIm1pbiIsCiAgInNlYyIsCiAgImp1bGRhdGUiLAogICJkaXZldHlwZSIsCiAgImV1cGhvdGljZGVwdGgiLAogICJ0aGVybW9jbGluZWRlcHRoIiwKICAiZGF5X2RlcGFydHVyZSIsCiAgInBoYXNlIiwKICAibGF0IiwKICAibG9uIiwKICAiZGlzdF9kZXAiLAogICJzcCIKKV0pCgojIGNhbHVsYXRlIHRoZSBtZWRpYW4gb2YgZHJpZnRyYXRlIGZvciBlYWNoIGRheQptZWRpYW5fZHJpZnRyYXRlIDwtIGRhdGFfMjAxOFtkaXZldHlwZSA9PSAiMjogZHJpZnQiLAogIC4oZHJpZnRyYXRlID0gcXVhbnRpbGUoZHJpZnRyYXRlLCAwLjUpKSwKICBieSA9IC4oZGF0ZSA9IGFzLkRhdGUoZGF0ZSksIC5pZCkKXQoKIyBsZXQncyBpZGVudGl0eSB3aGVuIHRoZSBzbW9vdGggY2hhbmdlcyBzaWduCmNoYW5nZXNfZHJpZnRyYXRlIDwtIG1lZGlhbl9kcmlmdHJhdGUgJT4lCiAgLlssIC4oCiAgICB5X3Ntb290aCA9IHByZWRpY3QobG9lc3MoZHJpZnRyYXRlIH4gYXMubnVtZXJpYyhkYXRlKSwgc3BhbiA9IDAuMjUpKSwKICAgIGRhdGUKICApLCBieSA9IC5pZF0gJT4lCiAgLltjKEZBTFNFLCBkaWZmKHNpZ24oeV9zbW9vdGgpKSAhPSAwKSwgXQpgYGAKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0xNCwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQpmb3IgKGkgaW4gbmFtZXNfZGlzcGxheSkgewogIGNhdCgiIyMjIyIsIGksICJ7LnVubGlzdGVkIC51bm51bWJlcmVkfSBcbiIpCiAgaWYgKGkgPT0gIm1heGRlcHRoIikgewogICAgcHJpbnQoCiAgICAgIGdncGxvdCgpICsKICAgICAgICBnZW9tX3BvaW50KAogICAgICAgICAgZGF0YSA9IGRhdGFfMjAxOF9maWx0ZXJbLCAuKAogICAgICAgICAgICAuaWQsCiAgICAgICAgICAgIGRhdGUsCiAgICAgICAgICAgIHRoZXJtb2NsaW5lZGVwdGgKICAgICAgICAgICldLAogICAgICAgICAgYWVzKAogICAgICAgICAgICB4ID0gYXMuRGF0ZShkYXRlKSwKICAgICAgICAgICAgeSA9IC10aGVybW9jbGluZWRlcHRoLAogICAgICAgICAgICBjb2xvdXIgPSAiVGhlcm1vY2xpbmUgKG0pIgogICAgICAgICAgKSwKICAgICAgICAgIGFscGhhID0gLjIsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBnZW9tX3BvaW50KAogICAgICAgICAgZGF0YSA9IGRhdGFfMjAxOF9maWx0ZXJbLCAuKAogICAgICAgICAgICAuaWQsCiAgICAgICAgICAgIGRhdGUsCiAgICAgICAgICAgIGV1cGhvdGljZGVwdGgKICAgICAgICAgICldLAogICAgICAgICAgYWVzKAogICAgICAgICAgICB4ID0gYXMuRGF0ZShkYXRlKSwKICAgICAgICAgICAgeSA9IC1ldXBob3RpY2RlcHRoLAogICAgICAgICAgICBjb2xvdXIgPSAiRXVwaG90aWMgKG0pIgogICAgICAgICAgKSwKICAgICAgICAgIGFscGhhID0gLjIsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBzY2FsZV9jb2xvdXJfbWFudWFsKAogICAgICAgICAgdmFsdWVzID0gYygKICAgICAgICAgICAgIlRoZXJtb2NsaW5lIChtKSIgPSAicmVkIiwKICAgICAgICAgICAgIkV1cGhvdGljIChtKSIgPSAiYmxhY2siCiAgICAgICAgICApLAogICAgICAgICAgbmFtZSA9ICJab25lIgogICAgICAgICkgKwogICAgICAgIG5ld19zY2FsZV9jb2xvcigpICsKICAgICAgICBnZW9tX3BvaW50KAogICAgICAgICAgZGF0YSA9IG1lbHQoZGF0YV8yMDE4X2ZpbHRlclssIC4oLmlkLCBkYXRlLCBnZXQoaSkpXSwKICAgICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF0ZSIpCiAgICAgICAgICApLAogICAgICAgICAgYWVzKAogICAgICAgICAgICB4ID0gYXMuRGF0ZShkYXRlKSwKICAgICAgICAgICAgeSA9IC12YWx1ZSwKICAgICAgICAgICAgY29sID0gLmlkCiAgICAgICAgICApLAogICAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgICBzaXplID0gLjUsCiAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFCiAgICAgICAgKSArCiAgICAgICAgZ2VvbV92bGluZSgKICAgICAgICAgIGRhdGEgPSBjaGFuZ2VzX2RyaWZ0cmF0ZSwKICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gZGF0ZSksIAogICAgICAgICAgbGluZXR5cGUgPSAyCiAgICAgICAgKSArCiAgICAgICAgZmFjZXRfd3JhcCguIH4gLmlkLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgICAgICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJW0vJVkiKSArCiAgICAgICAgbGFicyh4ID0gIkRhdGUiLCB5ID0gIk1heGltdW0gRGVwdGggKG0pIikgKwogICAgICAgIHRoZW1lX2pqbygpICsKICAgICAgICB0aGVtZSgKICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIgogICAgICAgICkpCiAgICBjYXQoIjxibG9ja3F1b3RlPiBDb25zaWRlcmluZyBgaW5kXzIwMTgwNzRgIGhhcyBzbGlnaHRseSBkaWZmZXJlbnQgdmFsdWVzIHRoYW4gb3RoZXIgaW5kaXZpZHVhbHMgZm9yIHRoZSB0aGVybW9jbGluZSBkZXB0aCwgaXQgd291bGQgYmUgaW50ZXJlc3RpbmcgdG8gc2VlIHdoZXJlIHRoZSBhbmltYWwgd2VudC4gPC9ibG9ja3F1b3RlPiIpCiAgfSBlbHNlIGlmIChpID09ICJkcmlmdHJhdGUiKSB7CiAgICBwcmludCgKICAgICAgZ2dwbG90KAogICAgICAgIGRhdGEgPSBtZWx0KGRhdGFfMjAxOF9maWx0ZXJbLCAuKC5pZCwgZGF0ZSwgZ2V0KGkpLCBkaXZldHlwZSldLCAKICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygiLmlkIiwgImRhdGUiLCAiZGl2ZXR5cGUiKSksCiAgICAgICAgYWVzKAogICAgICAgICAgeCA9IGFzLkRhdGUoZGF0ZSksCiAgICAgICAgICB5ID0gdmFsdWUsCiAgICAgICAgICBjb2wgPSBkaXZldHlwZQogICAgICAgICkKICAgICAgKSArCiAgICAgICAgZ2VvbV9wb2ludCgKICAgICAgICAgIGFscGhhID0gMSAvIDEwLAogICAgICAgICAgc2l6ZSA9IC41CiAgICAgICAgKSArCiAgICAgICAgZ2VvbV92bGluZSgKICAgICAgICAgIGRhdGEgPSBjaGFuZ2VzX2RyaWZ0cmF0ZSwKICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gZGF0ZSksIAogICAgICAgICAgbGluZXR5cGUgPSAyCiAgICAgICAgKSArCiAgICAgICAgZmFjZXRfd3JhcCguIH4gLmlkLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgICAgICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJW0vJVkiKSArCiAgICAgICAgbGFicyh4ID0gIkRhdGUiLCB5ID0gIkRyaWZ0IFJhdGUgJ20vcyIsIGNvbCA9ICJEaXZlIFR5cGUiKSArCiAgICAgICAgdGhlbWVfampvKCkgKwogICAgICAgIHRoZW1lKAogICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwKICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iCiAgICAgICAgKSArCiAgICAgICAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KAogICAgICAgICAgc2l6ZSA9IDcsCiAgICAgICAgICBhbHBoYSA9IDEKICAgICAgICApKSkKICAgICkKICB9IGVsc2UgewogICAgcHJpbnQoCiAgICAgIGdncGxvdCgKICAgICAgICBkYXRhID0gbWVsdChkYXRhXzIwMThfZmlsdGVyWywgLiguaWQsIGRhdGUsIGdldChpKSldLCAKICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygiLmlkIiwgImRhdGUiKSksCiAgICAgICAgYWVzKAogICAgICAgICAgeCA9IGFzLkRhdGUoZGF0ZSksCiAgICAgICAgICB5ID0gdmFsdWUsCiAgICAgICAgICBjb2wgPSAuaWQKICAgICAgICApCiAgICAgICkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFLAogICAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBnZW9tX3ZsaW5lKAogICAgICAgICAgZGF0YSA9IGNoYW5nZXNfZHJpZnRyYXRlLAogICAgICAgICAgYWVzKHhpbnRlcmNlcHQgPSBkYXRlKSwgCiAgICAgICAgICBsaW5ldHlwZSA9IDIKICAgICAgICApICsKICAgICAgICBnZW9tX3ZsaW5lKGRhdGEgPSBkYXRhVmxpbmUsIGFlcyh4aW50ZXJjZXB0ID0gYXMuRGF0ZShkYXRlKSksIGNvbG91ciA9ICJibGFjayIsIGxpbmV0eXBlPTIpICsKICAgICAgICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgICAgIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlbS8lWSIpICsKICAgICAgICBsYWJzKHggPSAiRGF0ZSIsIHkgPSBpKSArCiAgICAgICAgdGhlbWVfampvKCkgKwogICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCiAgICApCiAgfQogIAogIGNhdCgiXG4gXG4iKQp9CmBgYAoKVGhlIHZlcnRpY2FsIGRhc2hlZCBsaW5lcyByZXByZXNlbnQgY2hhbmdlcyBpbiBidW95YW5jeSAoc2VlIGB2aWduZXR0ZSgiYnVveWFuY3lfZGV0ZWN0IilgIGZvciBtb3JlIGluZm9ybWF0aW9uKQoKIyMjIHsudW5saXN0ZWQgLnVubnVtYmVyZWQgLnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0xNSwgcmVzdWx0cz0nYXNpcycsIGNhY2hlPVRSVUUsIGVjaG89RkFMU0V9CmZvciAoaSBpbiBuYW1lc19kaXNwbGF5KSB7CiAgY2F0KCIjIyMjIiwgaSwgInsudW5saXN0ZWQgLnVubnVtYmVyZWR9IFxuIikKICBpZiAoaSA9PSAibWF4ZGVwdGgiKSB7CiAgICBwcmludCgKICAgICAgZ2dwbG90KCkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBkYXRhID0gZGF0YV8yMDE4X2ZpbHRlclssIC4oCiAgICAgICAgICAgIC5pZCwKICAgICAgICAgICAgZGF0ZSwKICAgICAgICAgICAgdGhlcm1vY2xpbmVkZXB0aAogICAgICAgICAgKV0sCiAgICAgICAgICBhZXMoCiAgICAgICAgICAgIHggPSBhcy5EYXRlKGRhdGUpLAogICAgICAgICAgICB5ID0gLXRoZXJtb2NsaW5lZGVwdGgsCiAgICAgICAgICAgIGNvbG91ciA9ICJUaGVybW9jbGluZSAobSkiCiAgICAgICAgICApLAogICAgICAgICAgYWxwaGEgPSAuMiwKICAgICAgICAgIHNpemUgPSAuNQogICAgICAgICkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBkYXRhID0gZGF0YV8yMDE4X2ZpbHRlclssIC4oCiAgICAgICAgICAgIC5pZCwKICAgICAgICAgICAgZGF0ZSwKICAgICAgICAgICAgZXVwaG90aWNkZXB0aAogICAgICAgICAgKV0sCiAgICAgICAgICBhZXMoCiAgICAgICAgICAgIHggPSBhcy5EYXRlKGRhdGUpLAogICAgICAgICAgICB5ID0gLWV1cGhvdGljZGVwdGgsCiAgICAgICAgICAgIGNvbG91ciA9ICJFdXBob3RpYyAobSkiCiAgICAgICAgICApLAogICAgICAgICAgYWxwaGEgPSAuMiwKICAgICAgICAgIHNpemUgPSAuNQogICAgICAgICkgKwogICAgICAgIHNjYWxlX2NvbG91cl9tYW51YWwoCiAgICAgICAgICB2YWx1ZXMgPSBjKAogICAgICAgICAgICAiVGhlcm1vY2xpbmUgKG0pIiA9ICJyZWQiLAogICAgICAgICAgICAiRXVwaG90aWMgKG0pIiA9ICJibGFjayIKICAgICAgICAgICksCiAgICAgICAgICBuYW1lID0gIlpvbmUiCiAgICAgICAgKSArCiAgICAgICAgbmV3X3NjYWxlX2NvbG9yKCkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBkYXRhID0gbWVsdChkYXRhXzIwMThfZmlsdGVyWywgLiguaWQsIGRhdGUsIGdldChpKSldLCAKICAgICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF0ZSIpKSwKICAgICAgICAgIGFlcygKICAgICAgICAgICAgeCA9IGFzLkRhdGUoZGF0ZSksCiAgICAgICAgICAgIHkgPSAtdmFsdWUsCiAgICAgICAgICAgIGNvbCA9IC5pZAogICAgICAgICAgKSwKICAgICAgICAgIGFscGhhID0gMSAvIDEwLAogICAgICAgICAgc2l6ZSA9IC41LAogICAgICAgICAgc2hvdy5sZWdlbmQgPSBGQUxTRQogICAgICAgICkgKwogICAgICAgIGdlb21fdmxpbmUoCiAgICAgICAgICBkYXRhID0gY2hhbmdlc19kcmlmdHJhdGUsCiAgICAgICAgICBhZXMoeGludGVyY2VwdCA9IGRhdGUpLCAKICAgICAgICAgIGxpbmV0eXBlID0gMgogICAgICAgICkgKwogICAgICAgIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWUiKSArCiAgICAgICAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiVtLyVZIikgKwogICAgICAgIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJNYXhpbXVtIERlcHRoIChtKSIpICsKICAgICAgICB0aGVtZV9qam8oKSArCiAgICAgICAgdGhlbWUoCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLAogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIKICAgICAgICApCiAgICApCiAgICBjYXQoIjxibG9ja3F1b3RlPiBDb25zaWRlcmluZyBgaW5kXzIwMTgwNzRgIGhhcyBzbGlnaHRseSBkaWZmZXJlbnQgdmFsdWVzIHRoYW4gb3RoZXIgaW5kaXZpZHVhbHMgZm9yIHRoZSB0aGVybW9jbGluZSBkZXB0aCwgaXQgd291bGQgYmUgaW50ZXJlc3RpbmcgdG8gc2VlIHdoZXJlIHRoZSBhbmltYWwgd2VudC4gPC9ibG9ja3F1b3RlPiIpCiAgfSBlbHNlIGlmIChpID09ICJkcmlmdHJhdGUiKSB7CiAgICBwcmludCgKICAgICAgZ2dwbG90KAogICAgICAgIGRhdGEgPSBtZWx0KGRhdGFfMjAxOF9maWx0ZXJbLCAuKC5pZCwgZGF0ZSwgZ2V0KGkpLCBkaXZldHlwZSldLCAKICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygiLmlkIiwgImRhdGUiLCAiZGl2ZXR5cGUiKSksCiAgICAgICAgYWVzKAogICAgICAgICAgeCA9IGFzLkRhdGUoZGF0ZSksCiAgICAgICAgICB5ID0gdmFsdWUsCiAgICAgICAgICBjb2wgPSBkaXZldHlwZQogICAgICAgICkKICAgICAgKSArCiAgICAgICAgZ2VvbV9wb2ludCgKICAgICAgICAgIGFscGhhID0gMSAvIDEwLAogICAgICAgICAgc2l6ZSA9IC41CiAgICAgICAgKSArCiAgICAgICAgZ2VvbV92bGluZSgKICAgICAgICAgIGRhdGEgPSBjaGFuZ2VzX2RyaWZ0cmF0ZSwKICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gZGF0ZSksIAogICAgICAgICAgbGluZXR5cGUgPSAyCiAgICAgICAgKSArCiAgICAgICAgZmFjZXRfd3JhcCguIH4gLmlkLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgICAgICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJW0vJVkiKSArCiAgICAgICAgbGFicyh4ID0gIkRhdGUiLCB5ID0gIkRyaWZ0IFJhdGUgJ20vcyIsIGNvbCA9ICJEaXZlIFR5cGUiKSArCiAgICAgICAgdGhlbWVfampvKCkgKwogICAgICAgIHRoZW1lKAogICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwKICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iCiAgICAgICAgKSArCiAgICAgICAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KAogICAgICAgICAgc2l6ZSA9IDcsCiAgICAgICAgICBhbHBoYSA9IDEKICAgICAgICApKSkKICAgICkKICB9IGVsc2UgewogICAgcHJpbnQoCiAgICAgIGdncGxvdCgKICAgICAgICBkYXRhID0gbWVsdChkYXRhXzIwMThfZmlsdGVyWywgLiguaWQsIGRhdGUsIGdldChpKSldLCAKICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygiLmlkIiwgImRhdGUiKSksCiAgICAgICAgYWVzKAogICAgICAgICAgeCA9IGFzLkRhdGUoZGF0ZSksCiAgICAgICAgICB5ID0gdmFsdWUsCiAgICAgICAgICBjb2wgPSAuaWQKICAgICAgICApCiAgICAgICkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFLAogICAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBnZW9tX3ZsaW5lKAogICAgICAgICAgZGF0YSA9IGNoYW5nZXNfZHJpZnRyYXRlLAogICAgICAgICAgYWVzKHhpbnRlcmNlcHQgPSBkYXRlKSwgCiAgICAgICAgICBsaW5ldHlwZSA9IDIKICAgICAgICApICsKICAgICAgICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgICAgIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlbS8lWSIpICsKICAgICAgICBsYWJzKHggPSAiRGF0ZSIsIHkgPSBpKSArCiAgICAgICAgdGhlbWVfampvKCkgKwogICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCiAgICApCiAgfQogIAogIGNhdCgiXG4gXG4iKQp9CmBgYAoKIyMjIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9Cgo+IEZldyBxdWVzdGlvbnMsIHRoYXQgSSBzaG91bGQgbG9vayBpbnRvIGl0OgogID4KICA+ICogaXMgdGhlIGJpbW9kYWwgZGlzdHJpYnV0aW9uIG9mIGBkZHVyYXRpb25gLCBgZGVzY3RpbWVgIGR1ZSB0byBueWN0aGVtZXJhbCBtaWdyYXRpb24/CiAgPiAqIGlzIHRoZSBiaW1vZGFsIGRpc3RyaWJ1dGlvbiBvZiBgZGVzY3JhdGVgIChlc3BlY2lhbGx5IGZvciBgaW5kMjAxODA3MGAgYW5kIGBpbmRfMjAxODA3MmApIGR1ZSB0byBkcmlmdCBkaXZlPwogID4gKiBpcyBgbGlnaHRhdGJvdHRgIGNvdWxkIGJlIHVzZWQgdG8gaWRlbnRpZnkgYmlvbHVtaW5lc2NlbmNlLCBjYXVzZSBpdCBzZWVtcyB0aGVyZSBpcyBhIGxvdCBnb2luZyBvbiBhdCB0aGUgYm90dG9tPwogID4gKiBhcmUgdGhlIHZhcmlhdGlvbnMgb2JzZXJ2ZWQgZm9yIGBsaWdodGF0c3VyZmAgaXMgZHVlIHRvIG1vb24gY3ljbGU/CiAgPiAqIG5vdCBzdXJlIHdoeSBpcyB0aGVyZSBhIGJpbW9kYWwgZGlzdHJpYnV0aW9uIG9mIGB0ZW1wYXRib3R0YCEKICA+ICogYGRyaWZyYXRlYCB0aGF0IG9uZSBpcyBhd2Vzb21lISBUaGFua3MgdG8gYGRpdmV0eXBlYCB3ZSBjYW4gY2xlYXJseSBzZWUgYSBwYXR0ZXJuIG9mIGhvdyBkcmlmdHJhdGUgKGFuZCBzbyBidW95YW5jeSkgY2hhbmdlIGFjY29yZGluZyB0aW1lLgo+ICogdGhlIGJpbW9kYWwgZGlzdHJpYnV0aW9uIG9mIGB2ZXJ0aWNhbHNwZWVkOTBgIGFuZCBgdmVydGljYWxzcGVlZDk1YCBzaG91bGQgYmUgZHVlIHRvIGRyaWZ0IGRpdmUuCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMTYsIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRX0KIyBzYW1lIHBsb3Qgd2l0aCBhIGNvbG9yZWQgZm9yIHRoZSBwaGFzZSBvZiB0aGUgZGF5CmZvciAoaSBpbiBuYW1lc19kaXNwbGF5KSB7CiAgY2F0KCIjIyMjIiwgaSwgInstfSBcbiIpCiAgcHJpbnQoCiAgICBnZ3Bsb3QoCiAgICAgIGRhdGEgPSBtZWx0KGRhdGFfMjAxOF9maWx0ZXJbLCAuKC5pZCwgZGF0ZSwgZ2V0KGkpLCBwaGFzZSldLAogICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygKICAgICAgICAgICAgICAgICAgICAiLmlkIiwKICAgICAgICAgICAgICAgICAgICAiZGF0ZSIsCiAgICAgICAgICAgICAgICAgICAgInBoYXNlIgogICAgICAgICAgICAgICAgICApCiAgICAgICksCiAgICAgIGFlcygKICAgICAgICB4ID0gYXMuRGF0ZShkYXRlKSwKICAgICAgICB5ID0gdmFsdWUsCiAgICAgICAgY29sID0gcGhhc2UKICAgICAgKQogICAgKSArCiAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgc2l6ZSA9IC41CiAgICAgICkgKwogICAgICAgIGdlb21fdmxpbmUoCiAgICAgICAgICBkYXRhID0gY2hhbmdlc19kcmlmdHJhdGUsCiAgICAgICAgICBhZXMoeGludGVyY2VwdCA9IGRhdGUpLCAKICAgICAgICAgIGxpbmV0eXBlID0gMgogICAgICAgICkgKwogICAgICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgICBzY2FsZV94X2RhdGUoZGF0ZV9sYWJlbHMgPSAiJW0vJVkiKSArCiAgICAgIGxhYnMoeCA9ICJEYXRlIiwgeSA9IGkpICsKICAgICAgdGhlbWVfampvKCkgKwogICAgICB0aGVtZSgKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iCiAgICAgICkgKwogICAgICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoCiAgICAgICAgc2l6ZSA9IDcsCiAgICAgICAgYWxwaGEgPSAxCiAgICAgICkpKQogICkKICBjYXQoIlxuIFxuIikKfQpgYGAKClRoZSB2ZXJ0aWNhbCBkYXNoZWQgbGluZXMgcmVwcmVzZW50IGNoYW5nZXMgaW4gYnVveWFuY3kgKHNlZSBgdmlnbmV0dGUoImJ1b3lhbmN5X2RldGVjdCIpYCBmb3IgbW9yZSBpbmZvcm1hdGlvbikKCiMjIyB7LnVubGlzdGVkIC51bm51bWJlcmVkIC50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9CgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMTcsIHJlc3VsdHM9J2FzaXMnLCBjYWNoZT1UUlVFLCBlY2hvPUZBTFNFfQojIHNhbWUgcGxvdCB3aXRoIGEgY29sb3JlZCBmb3IgdGhlIHBoYXNlIG9mIHRoZSBkYXkKZm9yIChpIGluIG5hbWVzX2Rpc3BsYXkpIHsKICBjYXQoIiMjIyMiLCBpLCAiey19IFxuIikKICBwcmludCgKICAgIGdncGxvdCgKICAgICAgZGF0YSA9IG1lbHQoZGF0YV8yMDE4X2ZpbHRlclssIC4oLmlkLCBkYXRlLCBnZXQoaSksIHBoYXNlKV0sCiAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKAogICAgICAgICAgICAgICAgICAgICIuaWQiLAogICAgICAgICAgICAgICAgICAgICJkYXRlIiwKICAgICAgICAgICAgICAgICAgICAicGhhc2UiCiAgICAgICAgICAgICAgICAgICkKICAgICAgKSwKICAgICAgYWVzKAogICAgICAgIHggPSBhcy5EYXRlKGRhdGUpLAogICAgICAgIHkgPSB2YWx1ZSwKICAgICAgICBjb2wgPSBwaGFzZQogICAgICApCiAgICApICsKICAgICAgZ2VvbV9wb2ludCgKICAgICAgICBhbHBoYSA9IDEgLyAxMCwKICAgICAgICBzaXplID0gLjUKICAgICAgKSArCiAgICAgICAgZ2VvbV92bGluZSgKICAgICAgICAgIGRhdGEgPSBjaGFuZ2VzX2RyaWZ0cmF0ZSwKICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gZGF0ZSksIAogICAgICAgICAgbGluZXR5cGUgPSAyCiAgICAgICAgKSArCiAgICAgIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWUiKSArCiAgICAgIHNjYWxlX3hfZGF0ZShkYXRlX2xhYmVscyA9ICIlbS8lWSIpICsKICAgICAgbGFicyh4ID0gIkRhdGUiLCB5ID0gaSkgKwogICAgICB0aGVtZV9qam8oKSArCiAgICAgIHRoZW1lKAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIKICAgICAgKSArCiAgICAgIGd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdCgKICAgICAgICBzaXplID0gNywKICAgICAgICBhbHBoYSA9IDEKICAgICAgKSkpCiAgKQogIGNhdCgiXG4gXG4iKQp9CmBgYAoKIyMjIEFsbCBWYXJpYWJsZXMgZHVyaW5nIHRoZSBmaXJzdCBtb250aAoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTE4LCBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9CmZvciAoaSBpbiBuYW1lc19kaXNwbGF5KSB7CiAgY2F0KCIjIyMjIiwgaSwgInsudW5saXN0ZWQgLnVubnVtYmVyZWR9IFxuIikKICBpZiAoaSA9PSAibWF4ZGVwdGgiKSB7CiAgICBwcmludCgKICAgICAgZ2dwbG90KCkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBkYXRhID0gZGF0YV8yMDE4X2ZpbHRlcltkYXlfZGVwYXJ0dXJlIDwgMzIsIC4oCiAgICAgICAgICAgIC5pZCwKICAgICAgICAgICAgZGF5X2RlcGFydHVyZSwKICAgICAgICAgICAgdGhlcm1vY2xpbmVkZXB0aAogICAgICAgICAgKV0sCiAgICAgICAgICBhZXMoCiAgICAgICAgICAgIHggPSBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgICB5ID0gLXRoZXJtb2NsaW5lZGVwdGgsCiAgICAgICAgICAgIGNvbG91ciA9ICJUaGVybW9jbGluZSAobSkiLAogICAgICAgICAgICBncm91cCA9IGRheV9kZXBhcnR1cmUKICAgICAgICAgICksCiAgICAgICAgICBhbHBoYSA9IC4yLAogICAgICAgICAgc2l6ZSA9IC41CiAgICAgICAgKSArCiAgICAgICAgZ2VvbV9wb2ludCgKICAgICAgICAgIGRhdGEgPSBkYXRhXzIwMThfZmlsdGVyW2RheV9kZXBhcnR1cmUgPCAzMiwgLigKICAgICAgICAgICAgLmlkLAogICAgICAgICAgICBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgICBldXBob3RpY2RlcHRoCiAgICAgICAgICApXSwKICAgICAgICAgIGFlcygKICAgICAgICAgICAgeCA9IGRheV9kZXBhcnR1cmUsCiAgICAgICAgICAgIHkgPSAtZXVwaG90aWNkZXB0aCwKICAgICAgICAgICAgY29sb3VyID0gIkV1cGhvdGljIChtKSIsCiAgICAgICAgICAgIGdyb3VwID0gZGF5X2RlcGFydHVyZQogICAgICAgICAgKSwKICAgICAgICAgIGFscGhhID0gLjIsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBzY2FsZV9jb2xvdXJfbWFudWFsKAogICAgICAgICAgdmFsdWVzID0gYygKICAgICAgICAgICAgIlRoZXJtb2NsaW5lIChtKSIgPSAicmVkIiwKICAgICAgICAgICAgIkV1cGhvdGljIChtKSIgPSAiYmxhY2siCiAgICAgICAgICApLAogICAgICAgICAgbmFtZSA9ICJab25lIgogICAgICAgICkgKwogICAgICAgIG5ld19zY2FsZV9jb2xvcigpICsKICAgICAgICBnZW9tX2JveHBsb3QoCiAgICAgICAgICBkYXRhID0gbWVsdChkYXRhXzIwMThfZmlsdGVyW2RheV9kZXBhcnR1cmUgPCAzMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4oLmlkLCBkYXlfZGVwYXJ0dXJlLCBnZXQoaSkpXSwgCiAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygiLmlkIiwgImRheV9kZXBhcnR1cmUiKSksCiAgICAgICAgICBhZXMoCiAgICAgICAgICAgIHggPSBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgICB5ID0gLXZhbHVlLAogICAgICAgICAgICBjb2wgPSAuaWQsCiAgICAgICAgICAgIGdyb3VwID0gZGF5X2RlcGFydHVyZQogICAgICAgICAgKSwKICAgICAgICAgIGFscGhhID0gMSAvIDEwLAogICAgICAgICAgc2l6ZSA9IC41LAogICAgICAgICAgc2hvdy5sZWdlbmQgPSBGQUxTRQogICAgICAgICkgKwogICAgICAgIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWUiKSArCiAgICAgICAgbGFicyh4ID0gIiMgZGF5cyBzaW5jZSBkZXBhcnR1cmUiLCB5ID0gIk1heGltdW0gRGVwdGggKG0pIikgKwogICAgICAgIHRoZW1lX2pqbygpICsKICAgICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKICAgICkKICB9IGVsc2UgewogICAgcHJpbnQoCiAgICAgIGdncGxvdCgKICAgICAgICBkYXRhID0gbWVsdChkYXRhXzIwMThfZmlsdGVyW2RheV9kZXBhcnR1cmUgPCAzMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuKC5pZCwgZGF5X2RlcGFydHVyZSwgZ2V0KGkpKV0sIAogICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF5X2RlcGFydHVyZSIpKSwKICAgICAgICBhZXMoCiAgICAgICAgICB4ID0gZGF5X2RlcGFydHVyZSwKICAgICAgICAgIHkgPSB2YWx1ZSwKICAgICAgICAgIGNvbG9yID0gLmlkLAogICAgICAgICAgZ3JvdXAgPSBkYXlfZGVwYXJ0dXJlCiAgICAgICAgKQogICAgICApICsKICAgICAgICBnZW9tX2JveHBsb3QoCiAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFLAogICAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgICBzaXplID0gLjUKICAgICAgICApICsKICAgICAgICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgICAgIGxhYnMoeCA9ICIjIGRheXMgc2luY2UgZGVwYXJ0dXJlIiwgeSA9IGkpICsKICAgICAgICB0aGVtZV9qam8oKQogICAgKQogIH0KICBjYXQoIlxuIFxuIikKfQpgYGAKCiMjIyB7LnVubGlzdGVkIC51bm51bWJlcmVkIC50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9CgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMTksIHJlc3VsdHM9J2FzaXMnLCBjYWNoZT1UUlVFLCBlY2hvPUZBTFNFfQpmb3IgKGkgaW4gbmFtZXNfZGlzcGxheSkgewogIGNhdCgiIyMjIyIsIGksICJ7LnVubGlzdGVkIC51bm51bWJlcmVkfSBcbiIpCiAgaWYgKGkgPT0gIm1heGRlcHRoIikgewogICAgcHJpbnQoCiAgICAgIGdncGxvdCgpICsKICAgICAgICBnZW9tX3BvaW50KAogICAgICAgICAgZGF0YSA9IGRhdGFfMjAxOF9maWx0ZXJbZGF5X2RlcGFydHVyZSA8IDMyLCAuKAogICAgICAgICAgICAuaWQsCiAgICAgICAgICAgIGRheV9kZXBhcnR1cmUsCiAgICAgICAgICAgIHRoZXJtb2NsaW5lZGVwdGgKICAgICAgICAgICldLAogICAgICAgICAgYWVzKAogICAgICAgICAgICB4ID0gZGF5X2RlcGFydHVyZSwKICAgICAgICAgICAgeSA9IC10aGVybW9jbGluZWRlcHRoLAogICAgICAgICAgICBjb2xvdXIgPSAiVGhlcm1vY2xpbmUgKG0pIiwKICAgICAgICAgICAgZ3JvdXAgPSBkYXlfZGVwYXJ0dXJlCiAgICAgICAgICApLAogICAgICAgICAgYWxwaGEgPSAuMiwKICAgICAgICAgIHNpemUgPSAuNQogICAgICAgICkgKwogICAgICAgIGdlb21fcG9pbnQoCiAgICAgICAgICBkYXRhID0gZGF0YV8yMDE4X2ZpbHRlcltkYXlfZGVwYXJ0dXJlIDwgMzIsIC4oCiAgICAgICAgICAgIC5pZCwKICAgICAgICAgICAgZGF5X2RlcGFydHVyZSwKICAgICAgICAgICAgZXVwaG90aWNkZXB0aAogICAgICAgICAgKV0sCiAgICAgICAgICBhZXMoCiAgICAgICAgICAgIHggPSBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgICB5ID0gLWV1cGhvdGljZGVwdGgsCiAgICAgICAgICAgIGNvbG91ciA9ICJFdXBob3RpYyAobSkiLAogICAgICAgICAgICBncm91cCA9IGRheV9kZXBhcnR1cmUKICAgICAgICAgICksCiAgICAgICAgICBhbHBoYSA9IC4yLAogICAgICAgICAgc2l6ZSA9IC41CiAgICAgICAgKSArCiAgICAgICAgc2NhbGVfY29sb3VyX21hbnVhbCgKICAgICAgICAgIHZhbHVlcyA9IGMoCiAgICAgICAgICAgICJUaGVybW9jbGluZSAobSkiID0gInJlZCIsCiAgICAgICAgICAgICJFdXBob3RpYyAobSkiID0gImJsYWNrIgogICAgICAgICAgKSwKICAgICAgICAgIG5hbWUgPSAiWm9uZSIKICAgICAgICApICsKICAgICAgICBuZXdfc2NhbGVfY29sb3IoKSArCiAgICAgICAgZ2VvbV9ib3hwbG90KAogICAgICAgICAgZGF0YSA9IG1lbHQoZGF0YV8yMDE4X2ZpbHRlcltkYXlfZGVwYXJ0dXJlIDwgMzIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuKC5pZCwgZGF5X2RlcGFydHVyZSwgZ2V0KGkpKV0sIAogICAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9IGMoIi5pZCIsICJkYXlfZGVwYXJ0dXJlIikpLAogICAgICAgICAgYWVzKAogICAgICAgICAgICB4ID0gZGF5X2RlcGFydHVyZSwKICAgICAgICAgICAgeSA9IC12YWx1ZSwKICAgICAgICAgICAgY29sID0gLmlkLAogICAgICAgICAgICBncm91cCA9IGRheV9kZXBhcnR1cmUKICAgICAgICAgICksCiAgICAgICAgICBhbHBoYSA9IDEgLyAxMCwKICAgICAgICAgIHNpemUgPSAuNSwKICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UKICAgICAgICApICsKICAgICAgICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgICAgIGxhYnMoeCA9ICIjIGRheXMgc2luY2UgZGVwYXJ0dXJlIiwgeSA9ICJNYXhpbXVtIERlcHRoIChtKSIpICsKICAgICAgICB0aGVtZV9qam8oKSArCiAgICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCiAgICApCiAgfSBlbHNlIHsKICAgIHByaW50KAogICAgICBnZ3Bsb3QoCiAgICAgICAgZGF0YSA9IG1lbHQoZGF0YV8yMDE4X2ZpbHRlcltkYXlfZGVwYXJ0dXJlIDwgMzIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLiguaWQsIGRheV9kZXBhcnR1cmUsIGdldChpKSldLCAKICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gYygiLmlkIiwgImRheV9kZXBhcnR1cmUiKSksCiAgICAgICAgYWVzKAogICAgICAgICAgeCA9IGRheV9kZXBhcnR1cmUsCiAgICAgICAgICB5ID0gdmFsdWUsCiAgICAgICAgICBjb2xvciA9IC5pZCwKICAgICAgICAgIGdyb3VwID0gZGF5X2RlcGFydHVyZQogICAgICAgICkKICAgICAgKSArCiAgICAgICAgZ2VvbV9ib3hwbG90KAogICAgICAgICAgc2hvdy5sZWdlbmQgPSBGQUxTRSwKICAgICAgICAgIGFscGhhID0gMSAvIDEwLAogICAgICAgICAgc2l6ZSA9IC41CiAgICAgICAgKSArCiAgICAgICAgZmFjZXRfd3JhcCguIH4gLmlkLCBzY2FsZXMgPSAiZnJlZSIpICsKICAgICAgICBsYWJzKHggPSAiIyBkYXlzIHNpbmNlIGRlcGFydHVyZSIsIHkgPSBpKSArCiAgICAgICAgdGhlbWVfampvKCkKICAgICkKICB9CiAgY2F0KCJcbiBcbiIpCn0KYGBgCgojIyMgey51bmxpc3RlZCAudW5udW1iZXJlZH0KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0yMCwgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQpmb3IgKGkgaW4gbmFtZXNfZGlzcGxheSkgewogIGNhdCgiIyMjIyIsIGksICJ7LnVubGlzdGVkIC51bm51bWJlcmVkfSBcbiIpCiAgcHJpbnQoCiAgICBnZ3Bsb3QoCiAgICAgIGRhdGEgPSBtZWx0KGRhdGFfMjAxOF9maWx0ZXJbCiAgICAgICAgZGF5X2RlcGFydHVyZSA8IDMyLAogICAgICAgIC4oLmlkLCBkYXlfZGVwYXJ0dXJlLCBnZXQoaSksIHBoYXNlKQogICAgICBdLAogICAgICBpZC52YXJzID0gYygiLmlkIiwgImRheV9kZXBhcnR1cmUiLCAicGhhc2UiKQogICAgICApLAogICAgICBhZXMoCiAgICAgICAgeCA9IGRheV9kZXBhcnR1cmUsCiAgICAgICAgeSA9IHZhbHVlLAogICAgICAgIGNvbG9yID0gcGhhc2UsCiAgICAgICAgZ3JvdXAgPSBpbnRlcmFjdGlvbihkYXlfZGVwYXJ0dXJlLCBwaGFzZSksCiAgICAgICkKICAgICkgKwogICAgICBnZW9tX2JveHBsb3QoCiAgICAgICAgYWxwaGEgPSAxIC8gMTAsCiAgICAgICAgc2l6ZSA9IC41CiAgICAgICkgKwogICAgICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlIikgKwogICAgICBsYWJzKHggPSAiIyBkYXlzIHNpbmNlIGRlcGFydHVyZSIsIHkgPSBpKSArCiAgICAgIHRoZW1lX2pqbygpICsKICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCiAgKQogIGNhdCgiXG4gXG4iKQp9CmBgYAoKIyMjIHsudW5saXN0ZWQgLnVubnVtYmVyZWQgLnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0yMSwgcmVzdWx0cz0nYXNpcycsIGNhY2hlPVRSVUUsIGVjaG89RkFMU0V9CmZvciAoaSBpbiBuYW1lc19kaXNwbGF5KSB7CiAgY2F0KCIjIyMjIiwgaSwgInsudW5saXN0ZWQgLnVubnVtYmVyZWR9IFxuIikKICBwcmludCgKICAgIGdncGxvdCgKICAgICAgZGF0YSA9IG1lbHQoZGF0YV8yMDE4X2ZpbHRlclsKICAgICAgICBkYXlfZGVwYXJ0dXJlIDwgMzIsCiAgICAgICAgLiguaWQsIGRheV9kZXBhcnR1cmUsIGdldChpKSwgcGhhc2UpCiAgICAgIF0sCiAgICAgIGlkLnZhcnMgPSBjKCIuaWQiLCAiZGF5X2RlcGFydHVyZSIsICJwaGFzZSIpCiAgICAgICksCiAgICAgIGFlcygKICAgICAgICB4ID0gZGF5X2RlcGFydHVyZSwKICAgICAgICB5ID0gdmFsdWUsCiAgICAgICAgY29sb3IgPSBwaGFzZSwKICAgICAgICBncm91cCA9IGludGVyYWN0aW9uKGRheV9kZXBhcnR1cmUsIHBoYXNlKSwKICAgICAgKQogICAgKSArCiAgICAgIGdlb21fYm94cGxvdCgKICAgICAgICBhbHBoYSA9IDEgLyAxMCwKICAgICAgICBzaXplID0gLjUKICAgICAgKSArCiAgICAgIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWUiKSArCiAgICAgIGxhYnMoeCA9ICIjIGRheXMgc2luY2UgZGVwYXJ0dXJlIiwgeSA9IGkpICsKICAgICAgdGhlbWVfampvKCkgKwogICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKICApCiAgY2F0KCJcbiBcbiIpCn0KYGBgCgojIyMgQ29ycmVsYXRpb24KCkNhbiB3ZSBmaW5kIG5pY2UgY29ycmVsYXRpb24/CiAgCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0yMiwgZmlnLmNhcD0iQ29ycmVsYXRpb24gbWF0cml4IChjcm9zc2VzIGluZGljYXRlIG5vbiBzaWduaWZpY2FudCBjb3JyZWxhdGlvbikiLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9MTB9CiMgY29tcHV0ZSBjb3JyZWxhdGlvbgpjb3JyXzIwMTggPC0gcm91bmQoY29yKGRhdGFfMjAxOF9maWx0ZXJbLCBuYW1lc19kaXNwbGF5LCB3aXRoID0gRl0sCiAgICAgICAgICAgICAgICAgICAgICAgdXNlID0gInBhaXJ3aXNlLmNvbXBsZXRlLm9icyIKKSwgMSkKCiMgcmVwbGFjZSBOQSB2YWx1ZSBieSAwCmNvcnJfMjAxOFtpcy5uYShjb3JyXzIwMTgpXSA8LSAwCgojIGNvbXB1dGUgcF92YWx1ZXMKY29ycl9wXzIwMTggPC0gY29yX3BtYXQoZGF0YV8yMDE4X2ZpbHRlclssIG5hbWVzX2Rpc3BsYXksIHdpdGggPSBGXSkKCiMgcmVwbGFjZSBOQSB2YWx1ZSBieSAwCmNvcnJfcF8yMDE4W2lzLm5hKGNvcnJfcF8yMDE4KV0gPC0gMQoKIyBkaXNwbGF5CmdnY29ycnBsb3QoCiAgY29ycl8yMDE4LAogIHAubWF0ID0gY29ycl9wXzIwMTgsCiAgaGMub3JkZXIgPSBUUlVFLAogIG1ldGhvZCA9ICJjaXJjbGUiLAogIHR5cGUgPSAibG93ZXIiLAogIGdndGhlbWUgPSB0aGVtZV9qam8oKSwKICBzaWcubGV2ZWwgPSAwLjA1LAogIGNvbG9ycyA9ICBjKCIjMDBBRkJCIiwgIiNFN0I4MDAiLCAiI0ZDNEUwNyIpCikKYGBgCgpBbm90aGVyIHdheSB0byBzZWUgaXQ6CiAgCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0yM30KIyBmbGF0dGVuIGNvcnJlbGF0aW9uIG1hdHJpeApjb3JfcmVzdWx0XzIwMTggPC0gZmxhdF9jb3JfbWF0KGNvcnJfMjAxOCwgY29ycl9wXzIwMTgpCgojIGtlZXAgb25seSB0aGUgb25lIGFib3ZlIC43CmNvcl9yZXN1bHRfMjAxOFtjb3IgPj0gLjcsIF1bb3JkZXIoLWFicyhjb3IpKV0gJT4lCiAgc2FibGUoY2FwdGlvbiA9ICJQYWlyd2lzZSBjb3JyZWxhdGlvbiBhYm92ZSAwLjc1IGFuZCBhc3NvY2lhdGVkIHAtdmFsdWVzIikKYGBgCgo+IEkgZ3Vlc3Mgbm90aGluZyB1bmV4cGVjdGVkIGhlcmUsIEknbGwgaGF2ZSB0byBjaGVjayB3aXRoIFBhdHJpY2sgYWJvdXQgdGhlIGVmZmljaWVuY3kgOykKCiMjIERpdmUgVHlwZQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTI0LCBmaWcuY2FwPSJQcm9wb3J0aW9uIGRpdmUgdHlwZXMifQojIGRhdGFzZXQgdG8gcGxvdCBwcm9wb3J0aW9uYWwgYXJlYSBwbG90CmRhdGFfMjAxOF9maWx0ZXJbLCBzdW1faWQgOj0gLk4sIGJ5ID0gLiguaWQsIGRheV9kZXBhcnR1cmUpXSAlPiUKICAuWywgc3VtX2lkX2RheXMgOj0gLk4sIGJ5ID0gLiguaWQsIGRheV9kZXBhcnR1cmUsIGRpdmV0eXBlKV0gJT4lCiAgLlssIHByb3AgOj0gc3VtX2lkX2RheXMgLyBzdW1faWRdCmRhdGFQbG90IDwtIHVuaXF1ZShkYXRhXzIwMThfZmlsdGVyWywgLihwcm9wLCAuaWQsIGRpdmV0eXBlLCBkYXlfZGVwYXJ0dXJlKV0pCgojIGFyZWEgcGxvdApnZ3Bsb3QoZGF0YVBsb3QsIGFlcygKICB4ID0gYXMubnVtZXJpYyhkYXlfZGVwYXJ0dXJlKSwKICB5ID0gcHJvcCwKICBmaWxsID0gYXMuY2hhcmFjdGVyKGRpdmV0eXBlKQopKSArCiAgZ2VvbV9hcmVhKGFscGhhID0gMC42LCBzaXplID0gMSkgKwogIGZhY2V0X3dyYXAoLmlkIH4gLiwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfampvKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCiAgbGFicyh4ID0gIiMgb2YgZGF5cyBzaW5jZSBkZXBhcnR1cmUiLCAKICAgICAgIHkgPSAiUHJvcG9ydGlvbiBvZiBkaXZlcyIsIAogICAgICAgZmlsbCA9ICJEaXZlIHR5cGVzIikKYGBgCgojIyBEaXZlIGR1cmF0aW9uICp2cy4qIE1heGltdW0gZGVwdGggey50YWJzZXR9CgojIyMgQ29sb3JlZCBieSBJRAoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTI1LCBmaWcuY2FwPSJEaXZlIGR1cmF0aW9uIHZzLiBNYXhpbXVtIERlcHRoIGNvbG9yZWQgMjAxOC1pbmRpdmlkdWFscyJ9CiMgcGxvdApnZ3Bsb3QoZGF0YSA9IGRhdGFfMjAxOF9maWx0ZXIsIGFlcyh5ID0gZGR1cmF0aW9uLCB4ID0gbWF4ZGVwdGgsIGNvbCA9IC5pZCkpICsKICBnZW9tX3BvaW50KHNpemUgPSAuNSwgYWxwaGEgPSAuMSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGZhY2V0X3dyYXAoLmlkIH4gLikgKwogIGxhYnMoeCA9ICJNYXhpbXVtIGRlcHRoIChtKSIsIHkgPSAiRGl2ZSBkdXJhdGlvbiAocykiKSArCiAgdGhlbWVfampvKCkKYGBgCgojIyMgQ29sb3JlZCBieSBEaXZlIFR5cGUKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0yNiwgZmlnLmNhcD0iRGl2ZSBkdXJhdGlvbiB2cy4gTWF4aW11bSBEZXB0aCBjb2xvcmVkIGJ5IERpdmUgVHlwZSJ9CiMgcGxvdApnZ3Bsb3QoZGF0YSA9IGRhdGFfMjAxOF9maWx0ZXIsIGFlcyh5ID0gZGR1cmF0aW9uLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IG1heGRlcHRoLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sID0gZGl2ZXR5cGUpKSArCiAgZ2VvbV9wb2ludChzaXplID0gLjUsIGFscGhhID0gLjEpICsKICBmYWNldF93cmFwKC5pZCB+IC4pICsKICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDUsIGFscGhhID0gMSkpKSArCiAgbGFicyh4ID0gIk1heGltdW0gZGVwdGggKG0pIiwgeSA9ICJEaXZlIGR1cmF0aW9uIChzKSIpICsKICB0aGVtZV9qam8oKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCmBgYAoKIyMjIENvbG9yZWQgYnkgIyBkYXlzIHNpbmNlIGRlcGFydHVyZQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTI3LCBmaWcuY2FwPSJEaXZlIGR1cmF0aW9uIHZzLiBNYXhpbXVtIERlcHRoIGNvbG9yZWQgYnkgIyBkYXlzIHNpbmNlIGRlcGFydHVyZSJ9CiMgcGxvdApnZ3Bsb3QoZGF0YSA9IGRhdGFfMjAxOF9maWx0ZXJbLCBwcm9wX3RyYWNrIDo9IChkYXlfZGVwYXJ0dXJlICogMTAwKSAvIG1heChkYXlfZGVwYXJ0dXJlKSwgYnkgPSAuaWRdLCAKICAgICAgIGFlcyh5ID0gZGR1cmF0aW9uLCB4ID0gbWF4ZGVwdGgsIGNvbCA9IHByb3BfdHJhY2spKSArCiAgZ2VvbV9wb2ludChzaXplID0gLjUsIGFscGhhID0gLjEpICsKICBmYWNldF93cmFwKC5pZCB+IC4pICsKICBsYWJzKHggPSAiTWF4aW11bSBkZXB0aCAobSkiLCAKICAgICAgIHkgPSAiRGl2ZSBkdXJhdGlvbiAocykiLCAKICAgICAgIGNvbCA9ICJQcm9wb3J0aW9uIG9mIGNvbXBsZXRlZCB0cmFjayAoJSkiKSArCiAgc2NhbGVfY29sb3JfY29udGludW91cyh0eXBlID0gInZpcmlkaXMiKSArCiAgdGhlbWVfampvKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQpgYGAKCiMjIyBDb2xvcmVkIGJ5IHBoYXNlcyBvZiBkYXkKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0yOCwgZmlnLmNhcD0iRGl2ZSBkdXJhdGlvbiB2cy4gTWF4aW11bSBEZXB0aCBjb2xvcmVkIGJ5IHBoYXNlcyBvZiB0aGUgZGF5In0KIyBwbG90CmdncGxvdChkYXRhID0gZGF0YV8yMDE4X2ZpbHRlciwgYWVzKHkgPSBkZHVyYXRpb24sIHggPSBtYXhkZXB0aCwgY29sID0gcGhhc2UpKSArCiAgZ2VvbV9wb2ludChzaXplID0gLjUsIGFscGhhID0gLjEpICsKICBmYWNldF93cmFwKC5pZCB+IC4pICsKICBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDUsIGFscGhhID0gMSkpKSArCiAgbGFicyh4ID0gIk1heGltdW0gZGVwdGggKG0pIiwgCiAgICAgICB5ID0gIkRpdmUgZHVyYXRpb24gKHMpIiwgCiAgICAgICBjb2wgPSAiUGhhc2VzIG9mIHRoZSBkYXkiKSArCiAgdGhlbWVfampvKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQpgYGAKCj4gVGhlcmUgc2VlbXMgdG8gYmUgYSAqcGF0Y2gqIGZvciBoaWdoIGRlcHRocyAoZXNwZWNpYWxseSB2aXNpYmxlIGZvciBgaW5kMjAxODA3MGApLCBidXQgSSBkb24ndCBrbm93IHdoYXQgaXQgY291bGQgYmUgbGlua2VkIHRvLi4uCgojIyBEcmlmdCBSYXRlCgo+IEluIHRoZSBmb2xsb3dpbmcgZ3JhcGhzOgo+Cj4gKiBgZHJpZnRyYXRlYCBpcyBjYWxjdWxhdGVkIHVzaW5nIG9ubHkgYGRpdmV0eXBlID09ICIyOiBkcmlmdCJgCj4gKiB3aGVyZWFzIGFsbCB0aGUgb3RoZXJzIHZhcmlhYmxlcyBhcmUgY2FsY3VsYXRlZCBhbGwgZGl2ZXMgY29uc2lkZXJlZAoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTI5fQojIGJ1aWxkIGRhdGFzZXQKZGF0YVBsb3QgPC0gZGF0YV8yMDE4X2ZpbHRlcltkaXZldHlwZSA9PSAiMjogZHJpZnQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbWVkaWFuIGRyaWZ0IHJhdGUgZm9yIGRyaWZ0IGRpdmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuKGRyaWZ0cmF0ZSA9IG1lZGlhbihkcmlmdHJhdGUsIG5hLnJtID0gVCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gLiguaWQsIGRheV9kZXBhcnR1cmUpCl1bZGF0YV8yMDE4X2ZpbHRlclssCiAgICAgICAgICAgICAgICAgICAuKAogICAgICAgICAgICAgICAgICAgICAjIG1lZGlhbiBkaXZlIGR1cmF0aW9uIGFsbCBkaXZlcyBjb25zaWRlcmVkCiAgICAgICAgICAgICAgICAgICAgIGRkdXJhdGlvbiA9IG1lZGlhbihkZHVyYXRpb24sIG5hLnJtID0gVCksCiAgICAgICAgICAgICAgICAgICAgICMgbWVkaWFuIG1heCBkZXB0aCBhbGwgZGl2ZXMgY29uc2lkZXJlZAogICAgICAgICAgICAgICAgICAgICBtYXhkZXB0aCA9IG1lZGlhbihtYXhkZXB0aCwgbmEucm0gPSBUKSwKICAgICAgICAgICAgICAgICAgICAgIyBtZWRpYW4gYm90dG9tIGRpdmVzIGFsbCBkaXZlcyBjb25zaWRlcmVkCiAgICAgICAgICAgICAgICAgICAgIGJvdHR0aW1lID0gbWVkaWFuKGJvdHR0aW1lLCBuYS5ybSA9IFQpCiAgICAgICAgICAgICAgICAgICApLAogICAgICAgICAgICAgICAgICAgYnkgPSAuKC5pZCwgZGF5X2RlcGFydHVyZSkKXSwKb24gPSBjKCIuaWQiLCAiZGF5X2RlcGFydHVyZSIpCl0KYGBgCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMzAsIGZpZy5jYXA9IkRyaWZ0IHJhdGUgdnMuIEJvdHRvbSB0aW1lIn0KIyBwbG90CmdncGxvdChkYXRhUGxvdCwgYWVzKHggPSBib3R0dGltZSwgeSA9IGRyaWZ0cmF0ZSwgY29sID0gLmlkKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IC41LCBhbHBoYSA9IC41KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwogIGd1aWRlcyhjb2xvciA9ICJub25lIikgKwogIGZhY2V0X3dyYXAoLmlkIH4gLikgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDcwMCkpICsKICBsYWJzKHggPSAiRGFpbHkgbWVkaWFuIEJvdHRvbSB0aW1lIChzKSIsIAogICAgICAgeSA9ICJEYWlseSBtZWRpYW4gZHJpZnQgcmF0ZSAobS5zLTEpIikgKwogIHRoZW1lX2pqbygpCmBgYAoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTMxLCBmaWcuY2FwPSJEcmlmdCByYXRlIHZzLiBNYXhpbXVtIGRlcHRoIn0KIyBwbG90CmdncGxvdChkYXRhUGxvdCwgYWVzKHggPSBtYXhkZXB0aCwgeSA9IGRyaWZ0cmF0ZSwgY29sID0gLmlkKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IC41LCBhbHBoYSA9IC41KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwogIGd1aWRlcyhjb2xvciA9ICJub25lIikgKwogIGZhY2V0X3dyYXAoLmlkIH4gLikgKwogIGxhYnMoeCA9ICJEYWlseSBtZWRpYW4gTWF4aW11bSBkZXB0aCAobSkiLCAKICAgICAgIHkgPSAiRGFpbHkgbWVkaWFuIGRyaWZ0IHJhdGUgKG0ucy0xKSIpICsKICB0aGVtZV9qam8oKQpgYGAKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0zMiwgZmlnLmNhcD0iRHJpZnQgcmF0ZSB2cy4gRGl2ZSBkdXJhdGlvbiJ9CiMgcGxvdApnZ3Bsb3QoZGF0YVBsb3QsIGFlcyh4ID0gZGR1cmF0aW9uLCB5ID0gZHJpZnRyYXRlLCBjb2wgPSAuaWQpKSArCiAgZ2VvbV9wb2ludChzaXplID0gLjUsIGFscGhhID0gLjUpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArCiAgZ3VpZGVzKGNvbG9yID0gIm5vbmUiKSArCiAgZmFjZXRfd3JhcCguaWQgfiAuKSArCiAgbGFicyh4ID0gIkRhaWx5IG1lZGlhbiBEaXZlIGR1cmF0aW9uIChzKSIsIAogICAgICAgeSA9ICJEYWlseSBtZWRpYW4gZHJpZnQgcmF0ZSAobS5zLTEpIikgKwogIHRoZW1lX2pqbygpCmBgYAoKIyMgQmVoYXZpb3JhbCBBZXJvYmljIERpdmUgTGltaXQgKGJBREwpCgojIyMgW0Nvb2sgZXQgYWwgKDIwMDgpXShodHRwczovL3d3dy5zY2llbmNlZGlyZWN0LmNvbS9zY2llbmNlL2FydGljbGUvcGlpL1MwMDAzMzQ3MjA4MDAxMzZYP3ZpYSUzRGlodWIpCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMzMsIGZpZy5jYXA9IlBvc3QtZGl2ZSBkdXJhdGlvbiB2cy4gZGl2ZSBkdXJhdGlvbiJ9CiMgZGl2ZSBkdXJhdGlvbiB2cyBwZGkgYnkgZGF5cwpnZ3Bsb3QoZGF0YSA9IGRhdGFfMjAxOF9maWx0ZXJbcGRpIDwgMzAwLCBdLCBhZXMoCiAgeCA9IGRkdXJhdGlvbiwKICB5ID0gcGRpLAogIGNvbG9yID0gLmlkLAogIGdyb3VwID0gZGR1cmF0aW9uLAogIGZpbGwgPSAibm9uZSIKKSkgKwogIGdlb21fYm94cGxvdChzaG93LmxlZ2VuZCA9IEZBTFNFLCBvdXRsaWVyLmFscGhhID0gMC4wNSwgYWxwaGEgPSAwKSArCiAgbGFicyh4ID0gIkRpdmUgZHVyYXRpb24gKHMpIiwgeSA9ICJQb3N0LWRpdmUgZHVyYXRpb24gKHMpIikgKwogIGZhY2V0X3dyYXAoLiB+IC5pZCwgc2NhbGVzID0gImZyZWVfeCIpICsKICB0aGVtZV9qam8oKQpgYGAKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0zNCwgZmlnLmNhcD0iUG9zdC1kaXZlIGR1cmF0aW9uIHZzLiBkaXZlIGR1cmF0aW9uIChyYXcgZGF0YSkifQojIGRpdmUgZHVyYXRpb24gdnMgcGRpIGJ5IGRheXMKZ2dwbG90KGRhdGEgPSBkYXRhXzIwMThfZmlsdGVyW3BkaSA8IDMwMCxdLCBhZXMoeCA9IGRkdXJhdGlvbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBwZGksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IC5pZCkpICsKICBnZW9tX3BvaW50KHNob3cubGVnZW5kID0gRkFMU0UsIGFscGhhID0gMC4wNSkgKwogIGdlb21fc21vb3RoKAogICAgbWV0aG9kID0gImdhbSIsCiAgICBzaG93LmxlZ2VuZCA9IEZBTFNFLAogICAgY29sID0gImJsYWNrIiwKICAgIGxpbmV0eXBlID0gImRhc2hlZCIKICApICsKICBsYWJzKHggPSAiRGl2ZSBkdXJhdGlvbiAocykiLCB5ID0gIlBvc3QtZGl2ZSBkdXJhdGlvbiAocykiKSArCiAgZmFjZXRfd3JhcCguIH4gLmlkLCBzY2FsZXMgPSAiZnJlZV94IikgKwogIHRoZW1lX2pqbygpCmBgYApgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMzUsIGZpZy5jYXA9IlBvc3QtZGl2ZSBkdXJhdGlvbiAvIGRpdmUgZHVyYXRpb24gcmF0aW8gdnMuIGRheSBzaW5jZSBkZXBhcnR1cmUifQojIGRpdmUgZHVyYXRpb24gdnMgcGRpIGJ5IGRheXMKZ2dwbG90KAogIGRhdGEgPSBkYXRhXzIwMThfZmlsdGVyW3BkaSA8IDMwMCwgLiguaWQsIHBkaV9yYXRpbyA9IHBkaSAvIGRkdXJhdGlvbiwgZGF5X2RlcGFydHVyZSldLAogIGFlcygKICAgIHggPSBkYXlfZGVwYXJ0dXJlLAogICAgeSA9IHBkaV9yYXRpbywKICAgIGNvbG9yID0gLmlkLAogICAgZ3JvdXAgPSBkYXlfZGVwYXJ0dXJlLAogICAgZmlsbCA9ICJub25lIgogICkKKSArCiAgZ2VvbV9ib3hwbG90KHNob3cubGVnZW5kID0gRkFMU0UsCiAgICAgICAgICAgICAgIG91dGxpZXIuYWxwaGEgPSAwLjA1LAogICAgICAgICAgICAgICBhbHBoYSA9IDApICsKICBsYWJzKHggPSAiIyBkYXlzIHNpbmNlIGRlcGFydHVyZSIsIHkgPSAiUG9zdC1kaXZlIC8gRGl2ZSBkdXJhdGlvbiByYXRpbyIpICsKICBmYWNldF93cmFwKC4gfiAuaWQsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgIyB6b29tCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAsIDAuNCkpICsKICB0aGVtZV9qam8oKQpgYGAKCiMjIyBbU2hlcm8gZXQgKmFsLiogKDIwMTgpXShodHRwczovL3d3dy5yZXNlYXJjaGdhdGUubmV0L3B1YmxpY2F0aW9uLzIyMjY4MzA0Ml9Ub19icmVhdGhlX29yX25vdF90b19icmVhdGhlX09wdGltYWxfYnJlYXRoaW5nX2Flcm9iaWNfZGl2ZV9saW1pdF9hbmRfb3h5Z2VuX3N0b3Jlc19pbl9kZWVwLWRpdmluZ19ibHVlLWV5ZWRfc2hhZ3MpCgpCYXNlZCBvbiBbU2hlcm8gZXQgKmFsLiogKDIwMTgpXShodHRwczovL3d3dy5yZXNlYXJjaGdhdGUubmV0L3B1YmxpY2F0aW9uLzIyMjY4MzA0Ml9Ub19icmVhdGhlX29yX25vdF90b19icmVhdGhlX09wdGltYWxfYnJlYXRoaW5nX2Flcm9iaWNfZGl2ZV9saW1pdF9hbmRfb3h5Z2VuX3N0b3Jlc19pbl9kZWVwLWRpdmluZ19ibHVlLWV5ZWRfc2hhZ3MpLCB3ZSBkZWNpZGVkIHRvIGxvb2sgYXQgdGhlICpiQURMKiBhcyB0aGUgOTV0aCBwZXJjZW50aWxlIG9mIGRpdmUgZHVyYXRpb24gZWFjaCBkYXksIGZvciB0aG9zZSB3aXRoICRuIFxnZXEgNTAkLiBUaGlzIHRocmVzaG9sZCB3YXMgY2hvc2VuIGZvbGxvd2luZyB0aGlzIGZpZ3VyZToKCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC0zNiwgZmlnLmNhcD0iRGlzdHJpYnV0aW9uIG9mIHRoZSBudW1iZXIgb2YgZGl2ZXMgZWFjaCBkYXkuIFRoZSB0aHJlc2hvbGQgdXNlZCB0byBjYWxjdWxhdGUgYkFETCBpcyBmaXhlZCBhdCA1MCBkaXZlcyBwZXIgZGF5LiIsIGZpZy5oZWlnaHQ9M30KZ2dwbG90KGRhdGFfMjAxOF9maWx0ZXJbLC4obmJfZGl2ZXMgPSAuTiksIAogICAgICAgICAgICAgICAgICAgICAgICBieSA9IC4oLmlkLCBkYXlfZGVwYXJ0dXJlKV0sIAogICAgICAgYWVzKHg9bmJfZGl2ZXMsIGZpbGw9LmlkKSkgKwogIGdlb21faGlzdG9ncmFtKHNob3cubGVnZW5kID0gRkFMU0UpICsgCiAgZmFjZXRfZ3JpZCgufi5pZCkgKwogIGxhYnMoeT0iIyBvZiBkYXlzIiwgeCA9ICIjIG9mIGRpdmVzIHBlciBkYXkiKSArCiAgdGhlbWVfampvKCkKYGBgCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMzcsIGZpZy5jYXA9IkJlaGF2aW9yYWwgQURMIHZzLiBkcmlmdCByYXRlIGFsb25nIGFuaW1hbHMnIHRyaXAgKEFtIEkgdGhlIG9ubHkgb25lIHNlZWluZyBzb21lIGtpbmQgb2YgcmVsYXRpb25zaGlwPykifQojIHNlbGVjdCBkYXkgdGhhdCBoYXZlIGF0IGxlYXN0IDUwIGRpdmVzCmRheXNfdG9fa2VlcCA9IGRhdGFfMjAxOF9maWx0ZXJbLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4obmJfZGl2ZXMgPSAuTiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSAuKC5pZCwgZGF5X2RlcGFydHVyZSldICU+JQogIC5bbmJfZGl2ZXMgPj0gNTAsXQoKIyBrZWVwIG9ubHkgdGhvc2UgZGF5cwpkYXRhXzIwMThfZmlsdGVyX2NvbXBsZXRlX2RheSA9IG1lcmdlKGRhdGFfMjAxOF9maWx0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF5c190b19rZWVwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gYygiLmlkIiwgImRheV9kZXBhcnR1cmUiKSkKCiMgZGF0YSBwbG90CmRhdGFQbG90ID0gZGF0YV8yMDE4X2ZpbHRlcl9jb21wbGV0ZV9kYXlbZGl2ZXR5cGU9PSIxOiBmb3JhZ2luZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLihiYWRsID0gcXVhbnRpbGUoZGR1cmF0aW9uLCAwLjk1KSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSAuKC5pZCwgZGF5X2RlcGFydHVyZSldCgojIGNvbWJpbmUgdHdvIGRhdGFzZXRzIHRvIGJlIGFibGUgdG8gdXNlIGEgc2Vjb25kIGF4aXMKIyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80OTE4NTU4My90d28teS1heGVzLXdpdGgtZGlmZmVyZW50LXNjYWxlcy1mb3ItdHdvLWRhdGFzZXRzLWluLWdncGxvdDIKZGF0YU1lZ2FQbG90ID0gcmJpbmQoZGF0YV8yMDE4X2ZpbHRlcl9jb21wbGV0ZV9kYXlbZGl2ZXR5cGUgPT0gIjI6IGRyaWZ0Il0gJT4lCiAgICAgICAgICAgICAgICAgICAgICAgLlssIC4odyA9IC5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gZHJpZnRyYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSBkYXlfZGVwYXJ0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHogPSAic2Vjb25kX3Bsb3QiKV0sCiAgICAgICAgICAgICAgICAgICAgIGRhdGFQbG90WywgLigKICAgICAgICAgICAgICAgICAgICAgICB3ID0gLmlkLAogICAgICAgICAgICAgICAgICAgICAgICMgdHJpY2t5IG9uZQogICAgICAgICAgICAgICAgICAgICAgIHkgPSAoYmFkbCAvIDEwMDApIC0gMSwKICAgICAgICAgICAgICAgICAgICAgICB4ID0gZGF5X2RlcGFydHVyZSwKICAgICAgICAgICAgICAgICAgICAgICB6ID0gImZpcnN0X3Bsb3QiCiAgICAgICAgICAgICAgICAgICAgICldKQoKIyBwbG90CmdncGxvdCgpICsKICBnZW9tX3BvaW50KAogICAgZGF0YSA9IGRhdGFNZWdhUGxvdFt6ID09ICJzZWNvbmRfcGxvdCIsIF0sCiAgICBhZXMoeCA9IHgsIHkgPSB5KSwKICAgIGFscGhhID0gMSAvIDEwLAogICAgc2l6ZSA9IDAuNSwKICAgIGNvbG9yID0gImdyZXk0MCIsCiAgICBzaG93LmxlZ2VuZCA9IEZBTFNFCiAgKSArCiAgZ2VvbV9wYXRoKGRhdGEgPSBkYXRhTWVnYVBsb3RbeiA9PSAiZmlyc3RfcGxvdCIsIF0sCiAgICAgICAgICAgIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gdyksCiAgICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICAjIEZlYXR1cmVzIG9mIHRoZSBmaXJzdCBheGlzCiAgICBuYW1lID0gIkRyaWZ0IHJhdGUgKG0vcykiLAogICAgIyBBZGQgYSBzZWNvbmQgYXhpcyBhbmQgc3BlY2lmeSBpdHMgZmVhdHVyZXMKICAgIHNlYy5heGlzID0gc2VjX2F4aXMoIH4gKC4gKiAxMDAwKSArIDEwMDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJCZWhhdmlvcmFsIEFlcm9iaWMgRGl2ZSBMaW1pdCAocykiKQogICkgKwogIGxhYnMoeCA9ICIjIGRheXMgc2luY2UgZGVwYXJ0dXJlIikgKwogIGZhY2V0X3dyYXAodyB+IC4pICsKICB0aGVtZV9qam8oKQpgYGAKCj4gTG9va2luZyBhdCB0aGlzIGdyYXBoLCBJIHdhbnQgdG8gYmVsaWV2ZSB0aGF0IHRoZXJlIGlzIHNvbWUga2luZCBvZiByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgKmJBREwqIGFzIGRlZmluZWQgYnkgW1NoZXJvIGV0ICphbC4qICgyMDE4KV0oaHR0cHM6Ly93d3cucmVzZWFyY2hnYXRlLm5ldC9wdWJsaWNhdGlvbi8yMjI2ODMwNDJfVG9fYnJlYXRoZV9vcl9ub3RfdG9fYnJlYXRoZV9PcHRpbWFsX2JyZWF0aGluZ19hZXJvYmljX2RpdmVfbGltaXRfYW5kX294eWdlbl9zdG9yZXNfaW5fZGVlcC1kaXZpbmdfYmx1ZS1leWVkX3NoYWdzKSBhbmQgdGhlIGRyaWZ0IHJhdGUgKGFuZCBzbyBidXlvYW5jeSkuCgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtMzh9CiMgZ2V0IGJhZGwKZGF0YXBsb3RfMSA9IGRhdGFfMjAxOF9maWx0ZXJfY29tcGxldGVfZGF5WywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLihiYWRsID0gcXVhbnRpbGUoZGR1cmF0aW9uLCAwLjk1KSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gLiguaWQsIGRheV9kZXBhcnR1cmUpXQojIGdldCBkcmlmdHJhdGUKZGF0YXBsb3RfMiA9IGRhdGFfMjAxOF9maWx0ZXJfY29tcGxldGVfZGF5W2RpdmV0eXBlID09ICIyOiBkcmlmdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4oZHJpZnRyYXRlID0gbWVkaWFuKGRyaWZ0cmF0ZSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IC4oLmlkLCBkYXlfZGVwYXJ0dXJlKV0KCiMgbWVyZ2UKZGF0YVBsb3QgPSBtZXJnZShkYXRhcGxvdF8xLAogICAgICAgICAgICAgICAgIGRhdGFwbG90XzIsCiAgICAgICAgICAgICAgICAgYnkgPSBjKCIuaWQiLCAiZGF5X2RlcGFydHVyZSIpLAogICAgICAgICAgICAgICAgIGFsbCA9IFRSVUUpCgojIHBsb3QKZ2dwbG90KGRhdGEgPSBkYXRhUGxvdCwgYWVzKHggPSBiYWRsLCB5ID0gZHJpZnRyYXRlLCBjb2wgPSAuaWQpKSArCiAgZ2VvbV9wb2ludChzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZmFjZXRfd3JhcCguaWR+Liwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfampvKCkKYGBgCgojIyMgey51bmxpc3RlZCAudW5udW1iZXJlZCAudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQoKIyMjIyBpbmRfMjAxODA3MCB7LnVubGlzdGVkIC51bm51bWJlcmVkfQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTM5fQojIGluZF8yMDE4MDcwCnBsb3RfbHkoCiAgeCA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwNzAiLCBiYWRsXSwKICB5ID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA3MCIsIGRheV9kZXBhcnR1cmVdLAogIHogPSBkYXRhUGxvdFsuaWQgPT0gImluZF8yMDE4MDcwIiwgZHJpZnRyYXRlXSwKICB0eXBlID0gInNjYXR0ZXIzZCIsCiAgbW9kZSA9ICJtYXJrZXJzIiwKICBtYXJrZXIgPSBsaXN0KHNpemUgPSAyKSwKICBjb2xvciA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwNzAiLCBkYXlfZGVwYXJ0dXJlXQopICU+JSAKICBsYXlvdXQoc2NlbmUgPSBsaXN0KHhheGlzID0gbGlzdCh0aXRsZSA9ICdCZWhhdmlvcmFsIEFETCcpLAogICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gJyMgZGF5cyBzaW5jZSBkZXBhcnR1cmUnKSwKICAgICAgICAgICAgICAgICAgICAgIHpheGlzID0gbGlzdCh0aXRsZSA9ICdEcmlmdCByYXRlIChtL3MpJykpKQpgYGAKCiMjIyMgaW5kXzIwMTgwNzIgey51bmxpc3RlZCAudW5udW1iZXJlZH0KCmBgYHtyIGRhdGEtZXhwbG9yYXRpb24tMjAxOC00MH0KIyBpbmRfMjAxODA3MgpwbG90X2x5KAogIHggPSBkYXRhUGxvdFsuaWQgPT0gImluZF8yMDE4MDcyIiwgYmFkbF0sCiAgeSA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwNzIiLCBkYXlfZGVwYXJ0dXJlXSwKICB6ID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA3MiIsIGRyaWZ0cmF0ZV0sCiAgdHlwZSA9ICJzY2F0dGVyM2QiLAogIG1vZGUgPSAibWFya2VycyIsCiAgbWFya2VyID0gbGlzdChzaXplID0gMiksCiAgY29sb3IgPSBkYXRhUGxvdFsuaWQgPT0gImluZF8yMDE4MDcyIiwgZGF5X2RlcGFydHVyZV0KKSAlPiUgCiAgbGF5b3V0KHNjZW5lID0gbGlzdCh4YXhpcyA9IGxpc3QodGl0bGUgPSAnQmVoYXZpb3JhbCBBREwnKSwKICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICcjIGRheXMgc2luY2UgZGVwYXJ0dXJlJyksCiAgICAgICAgICAgICAgICAgICAgICB6YXhpcyA9IGxpc3QodGl0bGUgPSAnRHJpZnQgcmF0ZSAobS9zKScpKSkKYGBgCgojIyMjIGluZF8yMDE4MDc0IHsudW5saXN0ZWQgLnVubnVtYmVyZWR9CgpgYGB7ciBkYXRhLWV4cGxvcmF0aW9uLTIwMTgtNDF9CiMgaW5kXzIwMTgwNzQKcGxvdF9seSgKICB4ID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA3NCIsIGJhZGxdLAogIHkgPSBkYXRhUGxvdFsuaWQgPT0gImluZF8yMDE4MDc0IiwgZGF5X2RlcGFydHVyZV0sCiAgeiA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwNzQiLCBkcmlmdHJhdGVdLAogIHR5cGUgPSAic2NhdHRlcjNkIiwKICBtb2RlID0gIm1hcmtlcnMiLAogIG1hcmtlciA9IGxpc3Qoc2l6ZSA9IDIpLAogIGNvbG9yID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA3NCIsIGRheV9kZXBhcnR1cmVdCikgJT4lIAogIGxheW91dChzY2VuZSA9IGxpc3QoeGF4aXMgPSBsaXN0KHRpdGxlID0gJ0JlaGF2aW9yYWwgQURMJyksCiAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnIyBkYXlzIHNpbmNlIGRlcGFydHVyZScpLAogICAgICAgICAgICAgICAgICAgICAgemF4aXMgPSBsaXN0KHRpdGxlID0gJ0RyaWZ0IHJhdGUgKG0vcyknKSkpCmBgYAoKIyMjIyBpbmRfMjAxODA3MiB7LnVubGlzdGVkIC51bm51bWJlcmVkfQoKYGBge3IgZGF0YS1leHBsb3JhdGlvbi0yMDE4LTQyfQojIGluZF8yMDE4MDgwCnBsb3RfbHkoCiAgeCA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwODAiLCBiYWRsXSwKICB5ID0gZGF0YVBsb3RbLmlkID09ICJpbmRfMjAxODA4MCIsIGRheV9kZXBhcnR1cmVdLAogIHogPSBkYXRhUGxvdFsuaWQgPT0gImluZF8yMDE4MDgwIiwgZHJpZnRyYXRlXSwKICB0eXBlID0gInNjYXR0ZXIzZCIsCiAgbW9kZSA9ICJtYXJrZXJzIiwKICBtYXJrZXIgPSBsaXN0KHNpemUgPSAyKSwKICBjb2xvciA9IGRhdGFQbG90Wy5pZCA9PSAiaW5kXzIwMTgwODAiLCBkYXlfZGVwYXJ0dXJlXQopICU+JSAKICBsYXlvdXQoc2NlbmUgPSBsaXN0KHhheGlzID0gbGlzdCh0aXRsZSA9ICdCZWhhdmlvcmFsIEFETCcpLAogICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gJyMgZGF5cyBzaW5jZSBkZXBhcnR1cmUnKSwKICAgICAgICAgICAgICAgICAgICAgIHpheGlzID0gbGlzdCh0aXRsZSA9ICdEcmlmdCByYXRlIChtL3MpJykpKQpgYGAKCiMjIEdQUyBkYXRhCgpTaW5jZSB0aGlzIHBhcnQgaXMgdGltZSBjb25zdW1pbmcsIHdlIGRlZGljYXRlZCBhIHdob2xlIGFydGljbGUgKGB2aWduZXR0ZSgiZGF0YV9leHBsb3JhdGlvbl8yMDE4X21hcCIpYCkgdG8gcmVkdWNlIGNvbXBpbGF0aW9uIHRpbWUuCgpgYGB7cn0KIyBzYXZpbmcgdGhlIGRhdGFfMjAxOF9maWx0ZXIgZGF0YXNldApzYXZlUkRTKGRhdGFfMjAxOF9maWx0ZXIsIGZpbGUgPSAidG1wL2RhdGFfMjAxOF9maWx0ZXIucmRzIikKYGBgCgo=